| /* $Id: encryption.c 4537 2013-06-19 06:47:43Z riza $ */ |
| /* |
| * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com) |
| * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org> |
| * |
| * 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 <pjlib-util.h> |
| #include <pjlib.h> |
| |
| |
| #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) |
| { |
| enum { MILLION = 1000000 }; |
| int k; |
| pj_sha1_context context; |
| pj_uint8_t digest[20]; |
| char output[80]; |
| pj_pool_t *pool; |
| pj_uint8_t *block; |
| |
| 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 < MILLION; 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; |
| } |
| |
| /* million 'a' test, using block */ |
| pool = pj_pool_create(mem, "sha1test", 256, 512, NULL); |
| block = (pj_uint8_t*)pj_pool_alloc(pool, MILLION); |
| pj_memset(block, 'a', MILLION); |
| |
| pj_sha1_init(&context); |
| pj_sha1_update(&context, block, MILLION); |
| pj_sha1_final(&context, digest); |
| digest_to_hex(digest, output); |
| if (strcmp(output, sha1_test_results[2])) { |
| pj_pool_release(pool); |
| PJ_LOG(3, (THIS_FILE, " incorrect hash result for block update!")); |
| return -21; |
| } |
| |
| /* verify that original buffer was not modified */ |
| for (k=0; k<MILLION; ++k) { |
| if (block[k] != 'a') { |
| pj_pool_release(pool); |
| PJ_LOG(3, (THIS_FILE, " block was modified!")); |
| return -22; |
| } |
| } |
| |
| pj_pool_release(pool); |
| |
| /* 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<PJ_ARRAY_SIZE(rfc2202_test_vector); ++i) { |
| PJ_ASSERT_RETURN(pj_ansi_strlen(rfc2202_test_vector[i].input) == |
| rfc2202_test_vector[i].input_len, -50); |
| PJ_ASSERT_RETURN(pj_ansi_strlen(rfc2202_test_vector[i].key) == |
| rfc2202_test_vector[i].key_len, -52); |
| PJ_ASSERT_RETURN(rfc2202_test_vector[i].md5_digest==NULL || |
| pj_ansi_strlen(rfc2202_test_vector[i].md5_digest)<=16, |
| -54); |
| PJ_ASSERT_RETURN(rfc2202_test_vector[i].sha1_digest==NULL || |
| pj_ansi_strlen(rfc2202_test_vector[i].sha1_digest)<=20, |
| -56); |
| } |
| |
| /* Test HMAC-MD5 */ |
| PJ_LOG(3, (THIS_FILE, " HMAC-MD5 test vectors from rfc 2202..")); |
| for (i=0; i<PJ_ARRAY_SIZE(rfc2202_test_vector); ++i) { |
| pj_uint8_t digest_buf[18], *digest; |
| |
| if (rfc2202_test_vector[i].md5_digest == NULL) |
| continue; |
| |
| digest_buf[0] = '\0'; |
| digest_buf[17] = '\0'; |
| |
| digest = digest_buf+1; |
| |
| pj_hmac_md5((pj_uint8_t*)rfc2202_test_vector[i].input, |
| rfc2202_test_vector[i].input_len, |
| (pj_uint8_t*)rfc2202_test_vector[i].key, |
| rfc2202_test_vector[i].key_len, |
| digest); |
| |
| /* Check for overwrites */ |
| if (digest_buf[0] != '\0' || digest_buf[17] != '\0') { |
| PJ_LOG(3, (THIS_FILE, " error: overwriting outside buffer on test %d", i)); |
| return -60; |
| } |
| |
| /* Compare digest */ |
| if (pj_memcmp(rfc2202_test_vector[i].md5_digest, digest, 16)) { |
| PJ_LOG(3, (THIS_FILE, " error: digest mismatch on test %d", i)); |
| return -65; |
| } |
| } |
| |
| /* Test HMAC-SHA1 */ |
| PJ_LOG(3, (THIS_FILE, " HMAC-SHA1 test vectors from rfc 2202..")); |
| for (i=0; i<PJ_ARRAY_SIZE(rfc2202_test_vector); ++i) { |
| pj_uint8_t digest_buf[22], *digest; |
| |
| if (rfc2202_test_vector[i].sha1_digest == NULL) |
| continue; |
| |
| digest_buf[0] = '\0'; |
| digest_buf[21] = '\0'; |
| |
| digest = digest_buf+1; |
| |
| pj_hmac_sha1((pj_uint8_t*)rfc2202_test_vector[i].input, |
| rfc2202_test_vector[i].input_len, |
| (pj_uint8_t*)rfc2202_test_vector[i].key, |
| rfc2202_test_vector[i].key_len, |
| digest); |
| |
| /* Check for overwrites */ |
| if (digest_buf[0] != '\0' || digest_buf[21] != '\0') { |
| PJ_LOG(3, (THIS_FILE, " error: overwriting outside buffer on test %d", i)); |
| return -70; |
| } |
| |
| /* Compare digest */ |
| if (pj_memcmp(rfc2202_test_vector[i].sha1_digest, digest, 20)) { |
| PJ_LOG(3, (THIS_FILE, " error: digest mismatch on test %d", i)); |
| return -75; |
| } |
| } |
| |
| |
| /* Success */ |
| return 0; |
| } |
| |
| /* CRC32 test data, generated from crc32 test on a Linux box */ |
| struct crc32_test_t |
| { |
| char *input; |
| pj_uint32_t crc; |
| } crc32_test_data[] = |
| { |
| { |
| "", |
| 0x0 |
| }, |
| { |
| "Hello World", |
| 0x4a17b156 |
| }, |
| { |
| /* Something read from /dev/random */ |
| "\x21\x21\x98\x10\x62\x59\xbc\x58\x42\x24\xe5\xf3\x92\x0a\x68\x3c\xa7\x67\x73\xc3", |
| 0x506693be |
| }, |
| { |
| "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", |
| 0xcab11777 |
| }, |
| { |
| "123456789", |
| 0xCBF43926 |
| } |
| }; |
| |
| /* |
| * CRC32 test |
| */ |
| static int crc32_test(void) |
| { |
| unsigned i; |
| |
| PJ_LOG(3, (THIS_FILE, " crc32 test..")); |
| |
| /* testing pj_crc32_calc */ |
| for (i=0; i<PJ_ARRAY_SIZE(crc32_test_data); ++i) { |
| pj_uint32_t crc; |
| |
| crc = pj_crc32_calc((pj_uint8_t*)crc32_test_data[i].input, |
| pj_ansi_strlen(crc32_test_data[i].input)); |
| if (crc != crc32_test_data[i].crc) { |
| PJ_LOG(3,(THIS_FILE, " error: crc mismatch on test %d", i)); |
| return -80; |
| } |
| } |
| |
| /* testing incremental CRC32 calculation */ |
| for (i=0; i<PJ_ARRAY_SIZE(crc32_test_data); ++i) { |
| pj_crc32_context ctx; |
| pj_uint32_t crc0, crc1; |
| pj_size_t len; |
| |
| len = pj_ansi_strlen(crc32_test_data[i].input); |
| crc0 = pj_crc32_calc((pj_uint8_t*)crc32_test_data[i].input, len); |
| |
| pj_crc32_init(&ctx); |
| pj_crc32_update(&ctx, (pj_uint8_t*)crc32_test_data[i].input, |
| len / 2); |
| |
| if (len/2 > 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; |
| } |
| |
| enum |
| { |
| ENCODE = 1, |
| DECODE = 2, |
| ENCODE_DECODE = 3 |
| }; |
| |
| /* |
| * Base64 test vectors (RFC 4648) |
| */ |
| static struct base64_test_vec |
| { |
| const char *base256; |
| const char *base64; |
| unsigned flag; |
| } base64_test_vec[] = |
| { |
| { |
| "", |
| "", |
| ENCODE_DECODE |
| }, |
| { |
| "f", |
| "Zg==", |
| ENCODE_DECODE |
| }, |
| { |
| "fo", |
| "Zm8=", |
| ENCODE_DECODE |
| }, |
| { |
| "foo", |
| "Zm9v", |
| ENCODE_DECODE |
| }, |
| { |
| "foob", |
| "Zm9vYg==", |
| ENCODE_DECODE |
| }, |
| { |
| "fooba", |
| "Zm9vYmE=", |
| ENCODE_DECODE |
| }, |
| { |
| "foobar", |
| "Zm9vYmFy", |
| ENCODE_DECODE |
| }, |
| { |
| "\x14\xfb\x9c\x03\xd9\x7e", |
| "FPucA9l+", |
| ENCODE_DECODE |
| }, |
| { |
| "\x14\xfb\x9c\x03\xd9", |
| "FPucA9k=", |
| ENCODE_DECODE |
| }, |
| { |
| "\x14\xfb\x9c\x03", |
| "FPucAw==", |
| ENCODE_DECODE |
| }, |
| /* with whitespaces */ |
| { |
| "foobar", |
| "Zm9v\r\nYmFy", |
| DECODE |
| }, |
| { |
| "foobar", |
| "\nZ\r\nm 9\tv\nYm\nF\ny\n", |
| DECODE |
| }, |
| }; |
| |
| |
| 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<PJ_ARRAY_SIZE(base64_test_vec); ++i) { |
| pj_str_t input; |
| int out_len; |
| |
| /* Encode test */ |
| if (base64_test_vec[i].flag & ENCODE) { |
| out_len = sizeof(output); |
| rc = pj_base64_encode((pj_uint8_t*)base64_test_vec[i].base256, |
| (int)strlen(base64_test_vec[i].base256), |
| output, &out_len); |
| if (rc != PJ_SUCCESS) |
| return -90; |
| |
| if (out_len != (int)strlen(base64_test_vec[i].base64)) |
| return -91; |
| |
| output[out_len] = '\0'; |
| if (strcmp(output, base64_test_vec[i].base64) != 0) |
| return -92; |
| } |
| |
| /* Decode test */ |
| if (base64_test_vec[i].flag & DECODE) { |
| out_len = sizeof(output); |
| input.ptr = (char*)base64_test_vec[i].base64; |
| input.slen = strlen(base64_test_vec[i].base64); |
| rc = pj_base64_decode(&input, (pj_uint8_t*)output, &out_len); |
| if (rc != PJ_SUCCESS) |
| return -95; |
| |
| if (out_len != (int)strlen(base64_test_vec[i].base256)) |
| return -96; |
| |
| output[out_len] = '\0'; |
| |
| if (strcmp(output, base64_test_vec[i].base256) != 0) |
| return -97; |
| } |
| } |
| |
| return 0; |
| } |
| |
| |
| int encryption_test() |
| { |
| int rc; |
| |
| rc = base64_test(); |
| if (rc != 0) |
| return rc; |
| |
| rc = sha1_test1(); |
| if (rc != 0) |
| return rc; |
| |
| rc = sha1_test2(); |
| if (rc != 0) |
| return rc; |
| |
| rc = rfc2202_test(); |
| if (rc != 0) |
| return rc; |
| |
| rc = crc32_test(); |
| if (rc != 0) |
| return rc; |
| |
| return 0; |
| } |
| |
| static void crc32_update(pj_crc32_context *c, const pj_uint8_t *data, |
| pj_size_t nbytes) |
| { |
| pj_crc32_update(c, data, nbytes); |
| } |
| |
| static void crc32_final(pj_crc32_context *ctx, pj_uint32_t *digest) |
| { |
| *digest = pj_crc32_final(ctx); |
| } |
| |
| int encryption_benchmark() |
| { |
| pj_pool_t *pool; |
| pj_uint8_t *input; |
| union { |
| pj_md5_context md5_context; |
| pj_sha1_context sha1_context; |
| } context; |
| pj_uint8_t digest[32]; |
| pj_size_t input_len; |
| struct algorithm |
| { |
| const char *name; |
| void (*init_context)(void*); |
| void (*update)(void*, const pj_uint8_t*, unsigned); |
| void (*final)(void*, void*); |
| pj_uint32_t t; |
| } algorithms[] = |
| { |
| { |
| "MD5 ", |
| (void (*)(void*))&pj_md5_init, |
| (void (*)(void*, const pj_uint8_t*, unsigned))&pj_md5_update, |
| (void (*)(void*, void*))&pj_md5_final |
| }, |
| { |
| "SHA1 ", |
| (void (*)(void*))&pj_sha1_init, |
| (void (*)(void*, const pj_uint8_t*, unsigned))&pj_sha1_update, |
| (void (*)(void*, void*))&pj_sha1_final |
| }, |
| { |
| "CRC32", |
| (void (*)(void*))&pj_crc32_init, |
| (void (*)(void*, const pj_uint8_t*, unsigned))&crc32_update, |
| (void (*)(void*, void*))&crc32_final |
| } |
| }; |
| #if defined(PJ_DEBUG) && PJ_DEBUG!=0 |
| enum { LOOP = 1000 }; |
| #else |
| enum { LOOP = 10000 }; |
| #endif |
| unsigned i; |
| double total_len; |
| |
| input_len = 2048; |
| total_len = (unsigned)input_len * LOOP; |
| pool = pj_pool_create(mem, "enc", input_len+256, 0, NULL); |
| if (!pool) |
| return PJ_ENOMEM; |
| |
| input = (pj_uint8_t*)pj_pool_alloc(pool, input_len); |
| pj_memset(input, '\xaa', input_len); |
| |
| PJ_LOG(3, (THIS_FILE, " feeding %d Mbytes of data", |
| (unsigned)(total_len/1024/1024))); |
| |
| /* Dry run */ |
| for (i=0; i<PJ_ARRAY_SIZE(algorithms); ++i) { |
| algorithms[i].init_context(&context); |
| algorithms[i].update(&context, input, (unsigned)input_len); |
| algorithms[i].final(&context, digest); |
| } |
| |
| /* Run */ |
| for (i=0; i<PJ_ARRAY_SIZE(algorithms); ++i) { |
| int j; |
| pj_timestamp t1, t2; |
| |
| pj_get_timestamp(&t1); |
| algorithms[i].init_context(&context); |
| for (j=0; j<LOOP; ++j) { |
| algorithms[i].update(&context, input, (unsigned)input_len); |
| } |
| algorithms[i].final(&context, digest); |
| pj_get_timestamp(&t2); |
| |
| algorithms[i].t = pj_elapsed_usec(&t1, &t2); |
| } |
| |
| /* Results */ |
| for (i=0; i<PJ_ARRAY_SIZE(algorithms); ++i) { |
| double bytes; |
| |
| bytes = (total_len * 1000000 / algorithms[i].t); |
| PJ_LOG(3, (THIS_FILE, " %s:%8d usec (%3d.%03d Mbytes/sec)", |
| algorithms[i].name, algorithms[i].t, |
| (unsigned)(bytes / 1024 / 1024), |
| ((unsigned)(bytes) % (1024 * 1024)) / 1024)); |
| } |
| |
| return 0; |
| } |
| |
| |
| |
| #endif /* INCLUDE_ENCRYPTION_TEST */ |
| |