/* $Id$ */ /* * Copyright (C) 2003-2007 Benny Prijono * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "test.h" #include #include #if INCLUDE_ENCRYPTION_TEST /* * Encryption algorithm tests. */ #define THIS_FILE "encryption.c" /* * SHA1 test from the original sha1.c source file. */ static char *sha1_test_data[] = { "abc", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "A million repetitions of 'a'" }; static char *sha1_test_results[] = { "A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D", "84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1", "34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F" }; static void digest_to_hex(const pj_uint8_t digest[PJ_SHA1_DIGEST_SIZE], char *output) { int i,j; char *c = output; for (i = 0; i < PJ_SHA1_DIGEST_SIZE/4; i++) { for (j = 0; j < 4; j++) { sprintf(c,"%02X", digest[i*4+j]); c += 2; } sprintf(c, " "); c += 1; } *(c - 1) = '\0'; } static int sha1_test1(void) { int k; pj_sha1_context context; pj_uint8_t digest[20]; char output[80]; PJ_LOG(3, (THIS_FILE, " SHA1 test vector 1 from sha1.c..")); for (k = 0; k < 2; k++){ pj_sha1_init(&context); pj_sha1_update(&context, (pj_uint8_t*)sha1_test_data[k], pj_ansi_strlen(sha1_test_data[k])); pj_sha1_final(&context, digest); digest_to_hex(digest, output); if (pj_ansi_strcmp(output, sha1_test_results[k])) { PJ_LOG(3, (THIS_FILE, " incorrect hash result on k=%d", k)); return -10; } } /* million 'a' vector we feed separately */ pj_sha1_init(&context); for (k = 0; k < 1000000; k++) pj_sha1_update(&context, (pj_uint8_t*)"a", 1); pj_sha1_final(&context, digest); digest_to_hex(digest, output); if (strcmp(output, sha1_test_results[2])) { PJ_LOG(3, (THIS_FILE, " incorrect hash result!")); return -20; } /* success */ return(0); } /* * SHA1 test from RFC 3174 */ /* * Define patterns for testing */ #define TEST1 "abc" #define TEST2a "abcdbcdecdefdefgefghfghighijhi" #define TEST2b "jkijkljklmklmnlmnomnopnopq" #define TEST2 TEST2a TEST2b #define TEST3 "a" #define TEST4a "01234567012345670123456701234567" #define TEST4b "01234567012345670123456701234567" /* an exact multiple of 512 bits */ #define TEST4 TEST4a TEST4b static char *testarray[4] = { TEST1, TEST2, TEST3, TEST4 }; static int repeatcount[4] = { 1, 1, 1000000, 10 }; static char *resultarray[4] = { "A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D", "84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1", "34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F", "DEA356A2 CDDD90C7 A7ECEDC5 EBB56393 4F460452" }; static int sha1_test2(void) { pj_sha1_context sha; int i; pj_uint8_t digest[20]; char char_digest[64]; PJ_LOG(3, (THIS_FILE, " SHA1 test vector 2 from rfc 3174..")); for(i = 0; i < 4; ++i) { int j; pj_sha1_init(&sha); for(j = 0; j < repeatcount[i]; ++j) { pj_sha1_update(&sha, (const pj_uint8_t *) testarray[i], pj_ansi_strlen(testarray[i])); } pj_sha1_final(&sha, digest); digest_to_hex(digest, char_digest); if (pj_ansi_strcmp(char_digest, resultarray[i])) { PJ_LOG(3, (THIS_FILE, " digest mismatch in test %d", i)); return -40; } } return 0; } /* * HMAC-MD5 and HMAC-SHA1 test vectors from RFC 2202 */ struct rfc2202_test { char *key; unsigned key_len; char *input; unsigned input_len; char *md5_digest; char *sha1_digest; }; struct rfc2202_test rfc2202_test_vector[] = { { "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", 16, "Hi There", 8, "\x92\x94\x72\x7a\x36\x38\xbb\x1c\x13\xf4\x8e\xf8\x15\x8b\xfc\x9d", NULL }, { "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", 20, "Hi There", 8, NULL, "\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e\xf1\x46\xbe\x00" }, { "Jefe", 4, "what do ya want for nothing?", 28, "\x75\x0c\x78\x3e\x6a\xb0\xb5\x03\xea\xa8\x6e\x31\x0a\x5d\xb7\x38", "\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74\x16\xd5\xf1\x84\xdf\x9c\x25\x9a\x7c\x79" }, { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa", 16, "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd", 50, "\x56\xbe\x34\x52\x1d\x14\x4c\x88\xdb\xb8\xc7\x33\xf0\xe8\xb3\xf6", NULL }, { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 20, "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd", 50, NULL, "\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3\x9a\xf4\x8a\xa1\x7b\x4f\x63\xf1\x75\xd3" }, { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19", 25, "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd", 50, "\x69\x7e\xaf\x0a\xca\x3a\x3a\xea\x3a\x75\x16\x47\x46\xff\xaa\x79", "\x4c\x90\x07\xf4\x02\x62\x50\xc6\xbc\x84\x14\xf9\xbf\x50\xc8\x6c\x2d\x72\x35\xda" }, { "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c" "\x0c\x0c\x0c\x0c\x0c\x0c", 16, "Test With Truncation", 20, "\x56\x46\x1e\xf2\x34\x2e\xdc\x00\xf9\xba\xb9\x95\x69\x0e\xfd\x4c", NULL }, { "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c" "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c", 20, "Test With Truncation", 20, NULL, "\x4c\x1a\x03\x42\x4b\x55\xe0\x7f\xe7\xf2\x7b\xe1\xd5\x8b\xb9\x32\x4a\x9a\x5a\x04" }, { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 80, "Test Using Larger Than Block-Size Key - Hash Key First", 54, "\x6b\x1a\xb7\xfe\x4b\xd7\xbf\x8f\x0b\x62\xe6\xce\x61\xb9\xd0\xcd", "\xaa\x4a\xe5\xe1\x52\x72\xd0\x0e\x95\x70\x56\x37\xce\x8a\x3b\x55\xed\x40\x21\x12" }, { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 80, "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data", 73, "\x6f\x63\x0f\xad\x67\xcd\xa0\xee\x1f\xb1\xf5\x62\xdb\x3a\xa5\x3e", "\xe8\xe9\x9d\x0f\x45\x23\x7d\x78\x6d\x6b\xba\xa7\x96\x5c\x78\x08\xbb\xff\x1a\x91" } }; static int rfc2202_test(void) { unsigned i; PJ_LOG(3, (THIS_FILE, " verifying test vectors from rfc 2202..")); /* Verify that test vectors are valid */ for (i=0; i 0) { pj_crc32_update(&ctx, (pj_uint8_t*)crc32_test_data[i].input + len/2, len - len/2); } crc1 = pj_crc32_final(&ctx); if (crc0 != crc1) { PJ_LOG(3,(THIS_FILE, " error: crc algorithm error on test %d", i)); return -85; } } return 0; } /* * Base64 test vectors (RFC 4648) */ static struct base64_test_vec { const char *base256; const char *base64; } base64_test_vec[] = { { "", "" }, { "f", "Zg==" }, { "fo", "Zm8=" }, { "foo", "Zm9v" }, { "foob", "Zm9vYg==" }, { "fooba", "Zm9vYmE=", }, { "foobar", "Zm9vYmFy" }, { "\x14\xfb\x9c\x03\xd9\x7e", "FPucA9l+" }, { "\x14\xfb\x9c\x03\xd9", "FPucA9k=" }, { "\x14\xfb\x9c\x03", "FPucAw==" } }; static int base64_test(void) { unsigned i; char output[80]; pj_status_t rc; PJ_LOG(3, (THIS_FILE, " base64 test..")); for (i=0; i