~ubuntu-branches/ubuntu/trusty/sflphone/trusty

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject-2.0.1/pjlib-util/src/pjlib-util-test/encryption.c

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2014-01-28 18:23:36 UTC
  • mfrom: (4.3.4 sid)
  • Revision ID: package-import@ubuntu.com-20140128182336-jrsv0k9u6cawc068
Tags: 1.3.0-1
* New upstream release 
  - Fixes "New Upstream Release" (Closes: #735846)
  - Fixes "Ringtone does not stop" (Closes: #727164)
  - Fixes "[sflphone-kde] crash on startup" (Closes: #718178)
  - Fixes "sflphone GUI crashes when call is hung up" (Closes: #736583)
* Build-Depends: ensure GnuTLS 2.6
  - libucommon-dev (>= 6.0.7-1.1), libccrtp-dev (>= 2.0.6-3)
  - Fixes "FTBFS Build-Depends libgnutls{26,28}-dev" (Closes: #722040)
* Fix "boost 1.49 is going away" unversioned Build-Depends: (Closes: #736746)
* Add Build-Depends: libsndfile-dev, nepomuk-core-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Id: encryption.c 3553 2011-05-05 06:14:19Z nanang $ */
2
 
/*
3
 
 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4
 
 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
5
 
 *
6
 
 * This program is free software; you can redistribute it and/or modify
7
 
 * it under the terms of the GNU General Public License as published by
8
 
 * the Free Software Foundation; either version 2 of the License, or
9
 
 * (at your option) any later version.
10
 
 *
11
 
 * This program is distributed in the hope that it will be useful,
12
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
 * GNU General Public License for more details.
15
 
 *
16
 
 * You should have received a copy of the GNU General Public License
17
 
 * along with this program; if not, write to the Free Software
18
 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 
 */
20
 
#include "test.h"
21
 
#include <pjlib-util.h>
22
 
#include <pjlib.h>
23
 
 
24
 
 
25
 
#if INCLUDE_ENCRYPTION_TEST
26
 
 
27
 
/*
28
 
 * Encryption algorithm tests.
29
 
 */
30
 
#define THIS_FILE   "encryption.c"
31
 
 
32
 
 
33
 
/*
34
 
 * SHA1 test from the original sha1.c source file.
35
 
 */
36
 
static char *sha1_test_data[] = {
37
 
    "abc",
38
 
    "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
39
 
    "A million repetitions of 'a'"
40
 
};
41
 
static char *sha1_test_results[] = {
42
 
    "A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D",
43
 
    "84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1",
44
 
    "34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F"
45
 
};
46
 
 
47
 
 
48
 
static void digest_to_hex(const pj_uint8_t digest[PJ_SHA1_DIGEST_SIZE],
49
 
                          char *output)
50
 
{
51
 
    int i,j;
52
 
    char *c = output;
53
 
 
54
 
    for (i = 0; i < PJ_SHA1_DIGEST_SIZE/4; i++) {
55
 
        for (j = 0; j < 4; j++) {
56
 
            sprintf(c,"%02X", digest[i*4+j]);
57
 
            c += 2;
58
 
        }
59
 
        sprintf(c, " ");
60
 
        c += 1;
61
 
    }
62
 
    *(c - 1) = '\0';
63
 
}
64
 
 
65
 
static int sha1_test1(void)
66
 
{
67
 
    enum { MILLION = 1000000 };
68
 
    int k;
69
 
    pj_sha1_context context;
70
 
    pj_uint8_t digest[20];
71
 
    char output[80];
72
 
    pj_pool_t *pool;
73
 
    pj_uint8_t *block;
74
 
 
75
 
    PJ_LOG(3, (THIS_FILE, "  SHA1 test vector 1 from sha1.c.."));
76
 
 
77
 
    for (k = 0; k < 2; k++){
78
 
        pj_sha1_init(&context);
79
 
        pj_sha1_update(&context, (pj_uint8_t*)sha1_test_data[k],
80
 
                       pj_ansi_strlen(sha1_test_data[k]));
81
 
        pj_sha1_final(&context, digest);
82
 
        digest_to_hex(digest, output);
83
 
 
84
 
        if (pj_ansi_strcmp(output, sha1_test_results[k])) {
85
 
            PJ_LOG(3, (THIS_FILE, "    incorrect hash result on k=%d", k));
86
 
            return -10;
87
 
        }
88
 
    }
89
 
 
90
 
    /* million 'a' vector we feed separately */
91
 
    pj_sha1_init(&context);
92
 
    for (k = 0; k < MILLION; k++)
93
 
        pj_sha1_update(&context, (pj_uint8_t*)"a", 1);
94
 
    pj_sha1_final(&context, digest);
95
 
    digest_to_hex(digest, output);
96
 
    if (strcmp(output, sha1_test_results[2])) {
97
 
        PJ_LOG(3, (THIS_FILE, "    incorrect hash result!"));
98
 
        return -20;
99
 
    }
100
 
 
101
 
    /* million 'a' test, using block */
102
 
    pool = pj_pool_create(mem, "sha1test", 256, 512, NULL);
103
 
    block = (pj_uint8_t*)pj_pool_alloc(pool, MILLION);
104
 
    pj_memset(block, 'a', MILLION);
105
 
 
106
 
    pj_sha1_init(&context);
107
 
    pj_sha1_update(&context, block, MILLION);
108
 
    pj_sha1_final(&context, digest);
109
 
    digest_to_hex(digest, output);
110
 
    if (strcmp(output, sha1_test_results[2])) {
111
 
        pj_pool_release(pool);
112
 
        PJ_LOG(3, (THIS_FILE, "    incorrect hash result for block update!"));
113
 
        return -21;
114
 
    }
115
 
 
116
 
    /* verify that original buffer was not modified */
117
 
    for (k=0; k<MILLION; ++k) {
118
 
        if (block[k] != 'a') {
119
 
            pj_pool_release(pool);
120
 
            PJ_LOG(3, (THIS_FILE, "    block was modified!"));
121
 
            return -22;
122
 
        }
123
 
    }
124
 
 
125
 
    pj_pool_release(pool);
126
 
 
127
 
    /* success */
128
 
    return(0);
129
 
}
130
 
 
131
 
 
132
 
/*
133
 
 * SHA1 test from RFC 3174
134
 
 */
135
 
/*
136
 
 *  Define patterns for testing
137
 
 */
138
 
#define TEST1   "abc"
139
 
#define TEST2a  "abcdbcdecdefdefgefghfghighijhi"
140
 
#define TEST2b  "jkijkljklmklmnlmnomnopnopq"
141
 
#define TEST2   TEST2a TEST2b
142
 
#define TEST3   "a"
143
 
#define TEST4a  "01234567012345670123456701234567"
144
 
#define TEST4b  "01234567012345670123456701234567"
145
 
    /* an exact multiple of 512 bits */
146
 
#define TEST4   TEST4a TEST4b
147
 
 
148
 
static char *testarray[4] =
149
 
{
150
 
    TEST1,
151
 
    TEST2,
152
 
    TEST3,
153
 
    TEST4
154
 
};
155
 
static int repeatcount[4] = { 1, 1, 1000000, 10 };
156
 
static char *resultarray[4] =
157
 
{
158
 
    "A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D",
159
 
    "84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1",
160
 
    "34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F",
161
 
    "DEA356A2 CDDD90C7 A7ECEDC5 EBB56393 4F460452"
162
 
};
163
 
 
164
 
static int sha1_test2(void)
165
 
{
166
 
    pj_sha1_context sha;
167
 
    int i;
168
 
    pj_uint8_t digest[20];
169
 
    char char_digest[64];
170
 
 
171
 
    PJ_LOG(3, (THIS_FILE, "  SHA1 test vector 2 from rfc 3174.."));
172
 
 
173
 
    for(i = 0; i < 4; ++i) {
174
 
        int j;
175
 
 
176
 
        pj_sha1_init(&sha);
177
 
 
178
 
        for(j = 0; j < repeatcount[i]; ++j) {
179
 
            pj_sha1_update(&sha,
180
 
                           (const pj_uint8_t *) testarray[i],
181
 
                           pj_ansi_strlen(testarray[i]));
182
 
        }
183
 
 
184
 
        pj_sha1_final(&sha, digest);
185
 
 
186
 
        digest_to_hex(digest, char_digest);
187
 
        if (pj_ansi_strcmp(char_digest, resultarray[i])) {
188
 
            PJ_LOG(3, (THIS_FILE, "    digest mismatch in test %d", i));
189
 
            return -40;
190
 
        }
191
 
    }
192
 
 
193
 
    return 0;
194
 
}
195
 
 
196
 
 
197
 
/*
198
 
 * HMAC-MD5 and HMAC-SHA1 test vectors from RFC 2202
199
 
 */
200
 
struct rfc2202_test
201
 
{
202
 
    char       *key;
203
 
    unsigned    key_len;
204
 
    char       *input;
205
 
    unsigned    input_len;
206
 
    char       *md5_digest;
207
 
    char       *sha1_digest;
208
 
};
209
 
 
210
 
 
211
 
struct rfc2202_test rfc2202_test_vector[] =
212
 
{
213
 
    {
214
 
        "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
215
 
        16,
216
 
        "Hi There",
217
 
        8,
218
 
        "\x92\x94\x72\x7a\x36\x38\xbb\x1c\x13\xf4\x8e\xf8\x15\x8b\xfc\x9d",
219
 
        NULL
220
 
    },
221
 
    {
222
 
        "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
223
 
        "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
224
 
        20,
225
 
        "Hi There",
226
 
        8,
227
 
        NULL,
228
 
        "\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e\xf1\x46\xbe\x00"
229
 
    },
230
 
    {
231
 
        "Jefe",
232
 
        4,
233
 
        "what do ya want for nothing?",
234
 
        28,
235
 
        "\x75\x0c\x78\x3e\x6a\xb0\xb5\x03\xea\xa8\x6e\x31\x0a\x5d\xb7\x38",
236
 
        "\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74\x16\xd5\xf1\x84\xdf\x9c\x25\x9a\x7c\x79"
237
 
    },
238
 
    {
239
 
        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
240
 
        "\xaa\xaa\xaa\xaa\xaa\xaa",
241
 
        16,
242
 
        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
243
 
        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
244
 
        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
245
 
        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
246
 
        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd",
247
 
        50,
248
 
        "\x56\xbe\x34\x52\x1d\x14\x4c\x88\xdb\xb8\xc7\x33\xf0\xe8\xb3\xf6",
249
 
        NULL
250
 
    },
251
 
    {
252
 
        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
253
 
        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
254
 
        20,
255
 
        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
256
 
        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
257
 
        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
258
 
        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
259
 
        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd",
260
 
        50,
261
 
        NULL,
262
 
        "\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3\x9a\xf4\x8a\xa1\x7b\x4f\x63\xf1\x75\xd3"
263
 
    },
264
 
    {
265
 
        "\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",
266
 
        25,
267
 
        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
268
 
        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
269
 
        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
270
 
        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
271
 
        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd",
272
 
        50,
273
 
        "\x69\x7e\xaf\x0a\xca\x3a\x3a\xea\x3a\x75\x16\x47\x46\xff\xaa\x79",
274
 
        "\x4c\x90\x07\xf4\x02\x62\x50\xc6\xbc\x84\x14\xf9\xbf\x50\xc8\x6c\x2d\x72\x35\xda"
275
 
    },
276
 
    {
277
 
        "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
278
 
        "\x0c\x0c\x0c\x0c\x0c\x0c",
279
 
        16,
280
 
        "Test With Truncation",
281
 
        20,
282
 
        "\x56\x46\x1e\xf2\x34\x2e\xdc\x00\xf9\xba\xb9\x95\x69\x0e\xfd\x4c",
283
 
        NULL
284
 
    },
285
 
    {
286
 
        "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
287
 
        "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c",
288
 
        20,
289
 
        "Test With Truncation",
290
 
        20,
291
 
        NULL,
292
 
        "\x4c\x1a\x03\x42\x4b\x55\xe0\x7f\xe7\xf2\x7b\xe1\xd5\x8b\xb9\x32\x4a\x9a\x5a\x04"
293
 
    },
294
 
    {
295
 
        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
296
 
        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
297
 
        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
298
 
        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
299
 
        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
300
 
        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
301
 
        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
302
 
        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
303
 
        80,
304
 
        "Test Using Larger Than Block-Size Key - Hash Key First",
305
 
        54,
306
 
        "\x6b\x1a\xb7\xfe\x4b\xd7\xbf\x8f\x0b\x62\xe6\xce\x61\xb9\xd0\xcd",
307
 
        "\xaa\x4a\xe5\xe1\x52\x72\xd0\x0e\x95\x70\x56\x37\xce\x8a\x3b\x55\xed\x40\x21\x12"
308
 
    },
309
 
    {
310
 
        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
311
 
        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
312
 
        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
313
 
        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
314
 
        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
315
 
        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
316
 
        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
317
 
        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
318
 
        80,
319
 
        "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data",
320
 
        73,
321
 
        "\x6f\x63\x0f\xad\x67\xcd\xa0\xee\x1f\xb1\xf5\x62\xdb\x3a\xa5\x3e",
322
 
        "\xe8\xe9\x9d\x0f\x45\x23\x7d\x78\x6d\x6b\xba\xa7\x96\x5c\x78\x08\xbb\xff\x1a\x91"
323
 
    }
324
 
};
325
 
 
326
 
 
327
 
static int rfc2202_test(void)
328
 
{
329
 
    unsigned i;
330
 
 
331
 
    PJ_LOG(3, (THIS_FILE, "  verifying test vectors from rfc 2202.."));
332
 
 
333
 
    /* Verify that test vectors are valid */
334
 
    for (i=0; i<PJ_ARRAY_SIZE(rfc2202_test_vector); ++i) {
335
 
        PJ_ASSERT_RETURN(pj_ansi_strlen(rfc2202_test_vector[i].input) ==
336
 
                            rfc2202_test_vector[i].input_len, -50);
337
 
        PJ_ASSERT_RETURN(pj_ansi_strlen(rfc2202_test_vector[i].key) ==
338
 
                            rfc2202_test_vector[i].key_len, -52);
339
 
        PJ_ASSERT_RETURN(rfc2202_test_vector[i].md5_digest==NULL ||
340
 
                            pj_ansi_strlen(rfc2202_test_vector[i].md5_digest)<=16,
341
 
                            -54);
342
 
        PJ_ASSERT_RETURN(rfc2202_test_vector[i].sha1_digest==NULL ||
343
 
                            pj_ansi_strlen(rfc2202_test_vector[i].sha1_digest)<=20,
344
 
                            -56);
345
 
    }
346
 
 
347
 
    /* Test HMAC-MD5 */
348
 
    PJ_LOG(3, (THIS_FILE, "  HMAC-MD5 test vectors from rfc 2202.."));
349
 
    for (i=0; i<PJ_ARRAY_SIZE(rfc2202_test_vector); ++i) {
350
 
        pj_uint8_t digest_buf[18], *digest;
351
 
 
352
 
        if (rfc2202_test_vector[i].md5_digest == NULL)
353
 
            continue;
354
 
 
355
 
        digest_buf[0] = '\0';
356
 
        digest_buf[17] = '\0';
357
 
 
358
 
        digest = digest_buf+1;
359
 
 
360
 
        pj_hmac_md5((pj_uint8_t*)rfc2202_test_vector[i].input,
361
 
                    rfc2202_test_vector[i].input_len,
362
 
                    (pj_uint8_t*)rfc2202_test_vector[i].key,
363
 
                    rfc2202_test_vector[i].key_len,
364
 
                    digest);
365
 
 
366
 
        /* Check for overwrites */
367
 
        if (digest_buf[0] != '\0' || digest_buf[17] != '\0') {
368
 
            PJ_LOG(3, (THIS_FILE, "    error: overwriting outside buffer on test %d", i));
369
 
            return -60;
370
 
        }
371
 
 
372
 
        /* Compare digest */
373
 
        if (pj_memcmp(rfc2202_test_vector[i].md5_digest, digest, 16)) {
374
 
            PJ_LOG(3, (THIS_FILE, "    error: digest mismatch on test %d", i));
375
 
            return -65;
376
 
        }
377
 
    }
378
 
 
379
 
    /* Test HMAC-SHA1 */
380
 
    PJ_LOG(3, (THIS_FILE, "  HMAC-SHA1 test vectors from rfc 2202.."));
381
 
    for (i=0; i<PJ_ARRAY_SIZE(rfc2202_test_vector); ++i) {
382
 
        pj_uint8_t digest_buf[22], *digest;
383
 
 
384
 
        if (rfc2202_test_vector[i].sha1_digest == NULL)
385
 
            continue;
386
 
 
387
 
        digest_buf[0] = '\0';
388
 
        digest_buf[21] = '\0';
389
 
 
390
 
        digest = digest_buf+1;
391
 
 
392
 
        pj_hmac_sha1((pj_uint8_t*)rfc2202_test_vector[i].input,
393
 
                     rfc2202_test_vector[i].input_len,
394
 
                     (pj_uint8_t*)rfc2202_test_vector[i].key,
395
 
                     rfc2202_test_vector[i].key_len,
396
 
                     digest);
397
 
 
398
 
        /* Check for overwrites */
399
 
        if (digest_buf[0] != '\0' || digest_buf[21] != '\0') {
400
 
            PJ_LOG(3, (THIS_FILE, "    error: overwriting outside buffer on test %d", i));
401
 
            return -70;
402
 
        }
403
 
 
404
 
        /* Compare digest */
405
 
        if (pj_memcmp(rfc2202_test_vector[i].sha1_digest, digest, 20)) {
406
 
            PJ_LOG(3, (THIS_FILE, "    error: digest mismatch on test %d", i));
407
 
            return -75;
408
 
        }
409
 
    }
410
 
 
411
 
 
412
 
    /* Success */
413
 
    return 0;
414
 
}
415
 
 
416
 
/* CRC32 test data, generated from crc32 test on a Linux box */
417
 
struct crc32_test_t
418
 
{
419
 
    char            *input;
420
 
    pj_uint32_t      crc;
421
 
} crc32_test_data[] =
422
 
{
423
 
    {
424
 
        "",
425
 
        0x0
426
 
    },
427
 
    {
428
 
        "Hello World",
429
 
        0x4a17b156
430
 
    },
431
 
    {
432
 
        /* Something read from /dev/random */
433
 
        "\x21\x21\x98\x10\x62\x59\xbc\x58\x42\x24\xe5\xf3\x92\x0a\x68\x3c\xa7\x67\x73\xc3",
434
 
        0x506693be
435
 
    },
436
 
    {
437
 
        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
438
 
        0xcab11777
439
 
    },
440
 
    {
441
 
        "123456789",
442
 
        0xCBF43926
443
 
    }
444
 
};
445
 
 
446
 
/*
447
 
 * CRC32 test
448
 
 */
449
 
static int crc32_test(void)
450
 
{
451
 
    unsigned i;
452
 
 
453
 
    PJ_LOG(3, (THIS_FILE, "  crc32 test.."));
454
 
 
455
 
    /* testing pj_crc32_calc */
456
 
    for (i=0; i<PJ_ARRAY_SIZE(crc32_test_data); ++i) {
457
 
        pj_uint32_t crc;
458
 
 
459
 
        crc = pj_crc32_calc((pj_uint8_t*)crc32_test_data[i].input,
460
 
                            pj_ansi_strlen(crc32_test_data[i].input));
461
 
        if (crc != crc32_test_data[i].crc) {
462
 
            PJ_LOG(3,(THIS_FILE, "    error: crc mismatch on test %d", i));
463
 
            return -80;
464
 
        }
465
 
    }
466
 
 
467
 
    /* testing incremental CRC32 calculation */
468
 
    for (i=0; i<PJ_ARRAY_SIZE(crc32_test_data); ++i) {
469
 
        pj_crc32_context ctx;
470
 
        pj_uint32_t crc0, crc1;
471
 
        unsigned len;
472
 
 
473
 
        len = pj_ansi_strlen(crc32_test_data[i].input);
474
 
        crc0 = pj_crc32_calc((pj_uint8_t*)crc32_test_data[i].input, len);
475
 
 
476
 
        pj_crc32_init(&ctx);
477
 
        pj_crc32_update(&ctx, (pj_uint8_t*)crc32_test_data[i].input,
478
 
                        len / 2);
479
 
 
480
 
        if (len/2 > 0) {
481
 
            pj_crc32_update(&ctx, (pj_uint8_t*)crc32_test_data[i].input + len/2,
482
 
                            len - len/2);
483
 
        }
484
 
 
485
 
        crc1 = pj_crc32_final(&ctx);
486
 
 
487
 
        if (crc0 != crc1) {
488
 
            PJ_LOG(3,(THIS_FILE,
489
 
                      "    error: crc algorithm error on test %d", i));
490
 
            return -85;
491
 
        }
492
 
 
493
 
    }
494
 
    return 0;
495
 
}
496
 
 
497
 
enum
498
 
{
499
 
    ENCODE = 1,
500
 
    DECODE = 2,
501
 
    ENCODE_DECODE = 3
502
 
};
503
 
 
504
 
/*
505
 
 * Base64 test vectors (RFC 4648)
506
 
 */
507
 
static struct base64_test_vec
508
 
{
509
 
    const char *base256;
510
 
    const char *base64;
511
 
    unsigned flag;
512
 
} base64_test_vec[] =
513
 
{
514
 
    {
515
 
        "",
516
 
        "",
517
 
        ENCODE_DECODE
518
 
    },
519
 
    {
520
 
        "f",
521
 
        "Zg==",
522
 
        ENCODE_DECODE
523
 
    },
524
 
    {
525
 
        "fo",
526
 
        "Zm8=",
527
 
        ENCODE_DECODE
528
 
    },
529
 
    {
530
 
        "foo",
531
 
        "Zm9v",
532
 
        ENCODE_DECODE
533
 
    },
534
 
    {
535
 
        "foob",
536
 
        "Zm9vYg==",
537
 
        ENCODE_DECODE
538
 
    },
539
 
    {
540
 
        "fooba",
541
 
        "Zm9vYmE=",
542
 
        ENCODE_DECODE
543
 
    },
544
 
    {
545
 
        "foobar",
546
 
        "Zm9vYmFy",
547
 
        ENCODE_DECODE
548
 
    },
549
 
    {
550
 
        "\x14\xfb\x9c\x03\xd9\x7e",
551
 
        "FPucA9l+",
552
 
        ENCODE_DECODE
553
 
    },
554
 
    {
555
 
        "\x14\xfb\x9c\x03\xd9",
556
 
        "FPucA9k=",
557
 
        ENCODE_DECODE
558
 
    },
559
 
    {
560
 
        "\x14\xfb\x9c\x03",
561
 
        "FPucAw==",
562
 
        ENCODE_DECODE
563
 
    },
564
 
    /* with whitespaces */
565
 
    {
566
 
        "foobar",
567
 
        "Zm9v\r\nYmFy",
568
 
        DECODE
569
 
    },
570
 
    {
571
 
        "foobar",
572
 
        "\nZ\r\nm 9\tv\nYm\nF\ny\n",
573
 
        DECODE
574
 
    },
575
 
};
576
 
 
577
 
 
578
 
static int base64_test(void)
579
 
{
580
 
    unsigned i;
581
 
    char output[80];
582
 
    pj_status_t rc;
583
 
 
584
 
    PJ_LOG(3, (THIS_FILE, "  base64 test.."));
585
 
 
586
 
    for (i=0; i<PJ_ARRAY_SIZE(base64_test_vec); ++i) {
587
 
        pj_str_t input;
588
 
        int out_len;
589
 
 
590
 
        /* Encode test */
591
 
        if (base64_test_vec[i].flag & ENCODE) {
592
 
            out_len = sizeof(output);
593
 
            rc = pj_base64_encode((pj_uint8_t*)base64_test_vec[i].base256,
594
 
                                  strlen(base64_test_vec[i].base256),
595
 
                                  output, &out_len);
596
 
            if (rc != PJ_SUCCESS)
597
 
                return -90;
598
 
 
599
 
            if (out_len != (int)strlen(base64_test_vec[i].base64))
600
 
                return -91;
601
 
 
602
 
            output[out_len] = '\0';
603
 
            if (strcmp(output, base64_test_vec[i].base64) != 0)
604
 
                return -92;
605
 
        }
606
 
 
607
 
        /* Decode test */
608
 
        if (base64_test_vec[i].flag & DECODE) {
609
 
            out_len = sizeof(output);
610
 
            input.ptr = (char*)base64_test_vec[i].base64;
611
 
            input.slen = strlen(base64_test_vec[i].base64);
612
 
            rc = pj_base64_decode(&input, (pj_uint8_t*)output, &out_len);
613
 
            if (rc != PJ_SUCCESS)
614
 
                return -95;
615
 
 
616
 
            if (out_len != (int)strlen(base64_test_vec[i].base256))
617
 
                return -96;
618
 
 
619
 
            output[out_len] = '\0';
620
 
 
621
 
            if (strcmp(output, base64_test_vec[i].base256) != 0)
622
 
                return -97;
623
 
        }
624
 
    }
625
 
 
626
 
    return 0;
627
 
}
628
 
 
629
 
 
630
 
int encryption_test()
631
 
{
632
 
    int rc;
633
 
 
634
 
    rc = base64_test();
635
 
    if (rc != 0)
636
 
        return rc;
637
 
 
638
 
    rc = sha1_test1();
639
 
    if (rc != 0)
640
 
        return rc;
641
 
 
642
 
    rc = sha1_test2();
643
 
    if (rc != 0)
644
 
        return rc;
645
 
 
646
 
    rc = rfc2202_test();
647
 
    if (rc != 0)
648
 
        return rc;
649
 
 
650
 
    rc = crc32_test();
651
 
    if (rc != 0)
652
 
        return rc;
653
 
 
654
 
    return 0;
655
 
}
656
 
 
657
 
static void crc32_update(pj_crc32_context *c, const pj_uint8_t *data,
658
 
                         pj_size_t nbytes)
659
 
{
660
 
    pj_crc32_update(c, data, nbytes);
661
 
}
662
 
 
663
 
static void crc32_final(pj_crc32_context *ctx, pj_uint32_t *digest)
664
 
{
665
 
    *digest = pj_crc32_final(ctx);
666
 
}
667
 
 
668
 
int encryption_benchmark()
669
 
{
670
 
    pj_pool_t *pool;
671
 
    pj_uint8_t *input;
672
 
    union {
673
 
        pj_md5_context md5_context;
674
 
        pj_sha1_context sha1_context;
675
 
    } context;
676
 
    pj_uint8_t digest[32];
677
 
    pj_size_t input_len;
678
 
    struct algorithm
679
 
    {
680
 
        const char *name;
681
 
        void (*init_context)(void*);
682
 
        void (*update)(void*, const pj_uint8_t*, unsigned);
683
 
        void (*final)(void*, void*);
684
 
        pj_uint32_t t;
685
 
    } algorithms[] =
686
 
    {
687
 
        {
688
 
            "MD5  ",
689
 
            (void (*)(void*))&pj_md5_init,
690
 
            (void (*)(void*, const pj_uint8_t*, unsigned))&pj_md5_update,
691
 
            (void (*)(void*, void*))&pj_md5_final
692
 
        },
693
 
        {
694
 
            "SHA1 ",
695
 
            (void (*)(void*))&pj_sha1_init,
696
 
            (void (*)(void*, const pj_uint8_t*, unsigned))&pj_sha1_update,
697
 
            (void (*)(void*, void*))&pj_sha1_final
698
 
        },
699
 
        {
700
 
            "CRC32",
701
 
            (void (*)(void*))&pj_crc32_init,
702
 
            (void (*)(void*, const pj_uint8_t*, unsigned))&crc32_update,
703
 
            (void (*)(void*, void*))&crc32_final
704
 
        }
705
 
    };
706
 
#if defined(PJ_DEBUG) && PJ_DEBUG!=0
707
 
    enum { LOOP = 1000 };
708
 
#else
709
 
    enum { LOOP = 10000 };
710
 
#endif
711
 
    unsigned i;
712
 
    double total_len;
713
 
 
714
 
    input_len = 2048;
715
 
    total_len = input_len * LOOP;
716
 
    pool = pj_pool_create(mem, "enc", input_len+256, 0, NULL);
717
 
    if (!pool)
718
 
        return PJ_ENOMEM;
719
 
 
720
 
    input = (pj_uint8_t*)pj_pool_alloc(pool, input_len);
721
 
    pj_memset(input, '\xaa', input_len);
722
 
 
723
 
    PJ_LOG(3, (THIS_FILE, "  feeding %d Mbytes of data",
724
 
               (unsigned)(total_len/1024/1024)));
725
 
 
726
 
    /* Dry run */
727
 
    for (i=0; i<PJ_ARRAY_SIZE(algorithms); ++i) {
728
 
        algorithms[i].init_context(&context);
729
 
        algorithms[i].update(&context, input, input_len);
730
 
        algorithms[i].final(&context, digest);
731
 
    }
732
 
 
733
 
    /* Run */
734
 
    for (i=0; i<PJ_ARRAY_SIZE(algorithms); ++i) {
735
 
        int j;
736
 
        pj_timestamp t1, t2;
737
 
 
738
 
        pj_get_timestamp(&t1);
739
 
        algorithms[i].init_context(&context);
740
 
        for (j=0; j<LOOP; ++j) {
741
 
            algorithms[i].update(&context, input, input_len);
742
 
        }
743
 
        algorithms[i].final(&context, digest);
744
 
        pj_get_timestamp(&t2);
745
 
 
746
 
        algorithms[i].t = pj_elapsed_usec(&t1, &t2);
747
 
    }
748
 
 
749
 
    /* Results */
750
 
    for (i=0; i<PJ_ARRAY_SIZE(algorithms); ++i) {
751
 
        double bytes;
752
 
 
753
 
        bytes = (total_len * 1000000 / algorithms[i].t);
754
 
        PJ_LOG(3, (THIS_FILE, "    %s:%8d usec (%3d.%03d Mbytes/sec)",
755
 
                   algorithms[i].name, algorithms[i].t,
756
 
                   (unsigned)(bytes / 1024 / 1024),
757
 
                   ((unsigned)(bytes) % (1024 * 1024)) / 1024));
758
 
    }
759
 
 
760
 
    return 0;
761
 
}
762
 
 
763
 
 
764
 
 
765
 
#endif /* INCLUDE_ENCRYPTION_TEST */