Ignore:
Timestamp:
Jul 4, 2017 5:22:51 AM (7 years ago)
Author:
nanang
Message:

Close #1993: Updated bundled libSRTP version to 2.1.0.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/third_party/srtp/crypto/cipher/cipher.c

    r5261 r5614  
    66 * David A. McGrew 
    77 * Cisco Systems, Inc. 
    8  *  
     8 * 
    99 */ 
    1010 
    1111/* 
    12  *       
    13  * Copyright (c) 2001-2006,2013 Cisco Systems, Inc. 
     12 * 
     13 * Copyright (c) 2001-2017 Cisco Systems, Inc. 
    1414 * All rights reserved. 
    15  *  
     15 * 
    1616 * Redistribution and use in source and binary forms, with or without 
    1717 * modification, are permitted provided that the following conditions 
    1818 * are met: 
    19  *  
     19 * 
    2020 *   Redistributions of source code must retain the above copyright 
    2121 *   notice, this list of conditions and the following disclaimer. 
    22  *  
     22 * 
    2323 *   Redistributions in binary form must reproduce the above 
    2424 *   copyright notice, this list of conditions and the following 
    2525 *   disclaimer in the documentation and/or other materials provided 
    2626 *   with the distribution. 
    27  *  
     27 * 
    2828 *   Neither the name of the Cisco Systems, Inc. nor the names of its 
    2929 *   contributors may be used to endorse or promote products derived 
    3030 *   from this software without specific prior written permission. 
    31  *  
     31 * 
    3232 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
    3333 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
     
    5151#include "cipher.h" 
    5252#include "crypto_types.h" 
    53 #include "rand_source.h"        /* used in invertibiltiy tests        */ 
     53#include "err.h"                /* for srtp_debug */ 
    5454#include "alloc.h"              /* for crypto_alloc(), crypto_free()  */ 
    5555 
    56 debug_module_t mod_cipher = { 
    57   0,                 /* debugging is off by default */ 
    58   "cipher"           /* printable module name       */ 
     56srtp_debug_module_t srtp_mod_cipher = { 
     57    0,               /* debugging is off by default */ 
     58    "cipher"         /* printable module name       */ 
    5959}; 
    6060 
    61 err_status_t 
    62 cipher_output(cipher_t *c, uint8_t *buffer, int num_octets_to_output) { 
     61srtp_err_status_t srtp_cipher_type_alloc (const srtp_cipher_type_t *ct, srtp_cipher_t **c, int key_len, int tlen) 
     62{ 
     63    if (!ct || !ct->alloc) { 
     64        return (srtp_err_status_bad_param); 
     65    } 
     66    return ((ct)->alloc((c), (key_len), (tlen))); 
     67} 
     68 
     69srtp_err_status_t srtp_cipher_dealloc (srtp_cipher_t *c) 
     70{ 
     71    if (!c || !c->type) { 
     72        return (srtp_err_status_bad_param); 
     73    } 
     74    return (((c)->type)->dealloc(c)); 
     75} 
     76 
     77srtp_err_status_t srtp_cipher_init (srtp_cipher_t *c, const uint8_t *key) 
     78{ 
     79    if (!c || !c->type || !c->state) { 
     80        return (srtp_err_status_bad_param); 
     81    } 
     82    return (((c)->type)->init(((c)->state), (key))); 
     83} 
     84 
     85 
     86srtp_err_status_t srtp_cipher_set_iv (srtp_cipher_t *c, uint8_t *iv, int direction) 
     87{ 
     88    if (!c || !c->type || !c->state) { 
     89        return (srtp_err_status_bad_param); 
     90    } 
     91 
     92    return (((c)->type)->set_iv(((c)->state), iv, direction));  
     93} 
     94 
     95srtp_err_status_t srtp_cipher_output (srtp_cipher_t *c, uint8_t *buffer, uint32_t *num_octets_to_output) 
     96{ 
     97 
     98    /* zeroize the buffer */ 
     99    octet_string_set_to_zero(buffer, *num_octets_to_output); 
     100 
     101    /* exor keystream into buffer */ 
     102    return (((c)->type)->encrypt(((c)->state), buffer, num_octets_to_output)); 
     103} 
     104 
     105srtp_err_status_t srtp_cipher_encrypt (srtp_cipher_t *c, uint8_t *buffer, uint32_t *num_octets_to_output) 
     106{ 
     107    if (!c || !c->type || !c->state) { 
     108        return (srtp_err_status_bad_param); 
     109    } 
     110 
     111    return (((c)->type)->encrypt(((c)->state), buffer, num_octets_to_output)); 
     112} 
     113 
     114srtp_err_status_t srtp_cipher_decrypt (srtp_cipher_t *c, uint8_t *buffer, uint32_t *num_octets_to_output) 
     115{ 
     116    if (!c || !c->type || !c->state) { 
     117        return (srtp_err_status_bad_param); 
     118    } 
     119 
     120    return (((c)->type)->decrypt(((c)->state), buffer, num_octets_to_output)); 
     121} 
     122 
     123srtp_err_status_t srtp_cipher_get_tag (srtp_cipher_t *c, uint8_t *buffer, uint32_t *tag_len) 
     124{ 
     125    if (!c || !c->type || !c->state) { 
     126        return (srtp_err_status_bad_param); 
     127    } 
     128    if (!((c)->type)->get_tag) { 
     129        return (srtp_err_status_no_such_op); 
     130    } 
     131 
     132    return (((c)->type)->get_tag(((c)->state), buffer, tag_len)); 
     133} 
     134 
     135srtp_err_status_t srtp_cipher_set_aad (srtp_cipher_t *c, const uint8_t *aad, uint32_t aad_len) 
     136{ 
     137    if (!c || !c->type || !c->state) { 
     138        return (srtp_err_status_bad_param); 
     139    } 
     140    if (!((c)->type)->set_aad) { 
     141        return (srtp_err_status_no_such_op); 
     142    } 
     143 
     144    return (((c)->type)->set_aad(((c)->state), aad, aad_len)); 
     145} 
     146 
     147/* some bookkeeping functions */ 
     148 
     149int srtp_cipher_get_key_length (const srtp_cipher_t *c) 
     150{ 
     151    return c->key_len; 
     152} 
     153 
     154 
     155/* 
     156 * A trivial platform independent random source.  The random 
     157 * data is used for some of the cipher self-tests. 
     158 */ 
     159static srtp_err_status_t srtp_cipher_rand (void *dest, uint32_t len)  
     160{ 
     161#if defined(HAVE_RAND_S) 
     162  uint8_t *dst = (uint8_t *)dest; 
     163  while (len) 
     164  { 
     165    unsigned int val; 
     166    errno_t err = rand_s(&val); 
     167 
     168    if (err != 0) 
     169      return srtp_err_status_fail; 
    63170   
    64   /* zeroize the buffer */ 
    65   octet_string_set_to_zero(buffer, num_octets_to_output); 
    66    
    67   /* exor keystream into buffer */ 
    68   return cipher_encrypt(c, buffer, (unsigned int *) &num_octets_to_output); 
    69 } 
    70  
    71 /* some bookkeeping functions */ 
    72  
    73 int 
    74 cipher_get_key_length(const cipher_t *c) { 
    75   return c->key_len; 
    76 } 
    77  
    78 /*  
    79  * cipher_type_test(ct, test_data) tests a cipher of type ct against 
     171    *dst++ = val & 0xff; 
     172    len--; 
     173  } 
     174#else 
     175  /* Generic C-library (rand()) version */ 
     176  /* This is a random source of last resort */ 
     177  uint8_t *dst = (uint8_t *)dest; 
     178  while (len) 
     179  { 
     180          int val = rand(); 
     181          /* rand() returns 0-32767 (ugh) */ 
     182          /* Is this a good enough way to get random bytes? 
     183             It is if it passes FIPS-140... */ 
     184          *dst++ = val & 0xff; 
     185          len--; 
     186  } 
     187#endif 
     188  return srtp_err_status_ok; 
     189} 
     190  
     191#define SELF_TEST_BUF_OCTETS 128 
     192#define NUM_RAND_TESTS       128 
     193#define MAX_KEY_LEN          64 
     194/* 
     195 * srtp_cipher_type_test(ct, test_data) tests a cipher of type ct against 
    80196 * test cases provided in a list test_data of values of key, salt, iv, 
    81197 * plaintext, and ciphertext that is known to be good 
    82198 */ 
    83  
    84 #define SELF_TEST_BUF_OCTETS 128 
    85 #define NUM_RAND_TESTS       128 
    86 #define MAX_KEY_LEN          64 
    87  
    88 err_status_t 
    89 cipher_type_test(const cipher_type_t *ct, const cipher_test_case_t *test_data) { 
    90   const cipher_test_case_t *test_case = test_data; 
    91   cipher_t *c; 
    92   err_status_t status; 
    93   uint8_t buffer[SELF_TEST_BUF_OCTETS]; 
    94   uint8_t buffer2[SELF_TEST_BUF_OCTETS]; 
    95   int tag_len; 
    96   unsigned int len; 
    97   int i, j, case_num = 0; 
    98  
    99   debug_print(mod_cipher, "running self-test for cipher %s",  
    100               ct->description); 
    101    
    102   /* 
    103    * check to make sure that we have at least one test case, and 
    104    * return an error if we don't - we need to be paranoid here 
    105    */ 
    106   if (test_case == NULL) 
    107     return err_status_cant_check; 
    108  
    109   /* 
    110    * loop over all test cases, perform known-answer tests of both the 
    111    * encryption and decryption functions 
    112    */   
    113   while (test_case != NULL) { 
    114     /* allocate cipher */ 
    115     status = cipher_type_alloc(ct, &c, test_case->key_length_octets, test_case->tag_length_octets); 
    116     if (status) 
    117       return status; 
    118      
     199srtp_err_status_t srtp_cipher_type_test (const srtp_cipher_type_t *ct, const srtp_cipher_test_case_t *test_data) 
     200{ 
     201    const srtp_cipher_test_case_t *test_case = test_data; 
     202    srtp_cipher_t *c; 
     203    srtp_err_status_t status; 
     204    uint8_t buffer[SELF_TEST_BUF_OCTETS]; 
     205    uint8_t buffer2[SELF_TEST_BUF_OCTETS]; 
     206    uint32_t tag_len; 
     207    unsigned int len; 
     208    int i, j, case_num = 0; 
     209 
     210    debug_print(srtp_mod_cipher, "running self-test for cipher %s", 
     211                ct->description); 
     212 
    119213    /* 
    120      * test the encrypt function  
     214     * check to make sure that we have at least one test case, and 
     215     * return an error if we don't - we need to be paranoid here 
    121216     */ 
    122     debug_print(mod_cipher, "testing encryption", NULL);     
    123      
    124     /* initialize cipher */ 
    125     status = cipher_init(c, test_case->key); 
     217    if (test_case == NULL) { 
     218        return srtp_err_status_cant_check; 
     219    } 
     220 
     221    /* 
     222     * loop over all test cases, perform known-answer tests of both the 
     223     * encryption and decryption functions 
     224     */ 
     225    while (test_case != NULL) { 
     226        /* allocate cipher */ 
     227        status = srtp_cipher_type_alloc(ct, &c, test_case->key_length_octets, test_case->tag_length_octets); 
     228        if (status) { 
     229            return status; 
     230        } 
     231 
     232        /* 
     233         * test the encrypt function 
     234         */ 
     235        debug_print(srtp_mod_cipher, "testing encryption", NULL); 
     236 
     237        /* initialize cipher */ 
     238        status = srtp_cipher_init(c, test_case->key); 
     239        if (status) { 
     240            srtp_cipher_dealloc(c); 
     241            return status; 
     242        } 
     243 
     244        /* copy plaintext into test buffer */ 
     245        if (test_case->ciphertext_length_octets > SELF_TEST_BUF_OCTETS) { 
     246            srtp_cipher_dealloc(c); 
     247            return srtp_err_status_bad_param; 
     248        } 
     249        for (i = 0; i < test_case->plaintext_length_octets; i++) { 
     250            buffer[i] = test_case->plaintext[i]; 
     251        } 
     252 
     253        debug_print(srtp_mod_cipher, "plaintext:    %s", 
     254                    srtp_octet_string_hex_string(buffer, 
     255                                                 test_case->plaintext_length_octets)); 
     256 
     257        /* set the initialization vector */ 
     258        status = srtp_cipher_set_iv(c, (uint8_t*)test_case->idx, srtp_direction_encrypt); 
     259        if (status) { 
     260            srtp_cipher_dealloc(c); 
     261            return status; 
     262        } 
     263 
     264        if (c->algorithm == SRTP_AES_GCM_128 || c->algorithm == SRTP_AES_GCM_256) { 
     265            debug_print(srtp_mod_cipher, "IV:    %s", 
     266                        srtp_octet_string_hex_string(test_case->idx, 12)); 
     267 
     268            /* 
     269             * Set the AAD 
     270             */ 
     271            status = srtp_cipher_set_aad(c, test_case->aad, test_case->aad_length_octets); 
     272            if (status) { 
     273                srtp_cipher_dealloc(c); 
     274                return status; 
     275            } 
     276            debug_print(srtp_mod_cipher, "AAD:    %s", 
     277                        srtp_octet_string_hex_string(test_case->aad, 
     278                                                     test_case->aad_length_octets)); 
     279        } 
     280 
     281        /* encrypt */ 
     282        len = test_case->plaintext_length_octets; 
     283        status = srtp_cipher_encrypt(c, buffer, &len); 
     284        if (status) { 
     285            srtp_cipher_dealloc(c); 
     286            return status; 
     287        } 
     288 
     289        if (c->algorithm == SRTP_AES_GCM_128 || c->algorithm == SRTP_AES_GCM_256) { 
     290            /* 
     291             * Get the GCM tag 
     292             */ 
     293            status = srtp_cipher_get_tag(c, buffer + len, &tag_len); 
     294            if (status) { 
     295                srtp_cipher_dealloc(c); 
     296                return status; 
     297            } 
     298            len += tag_len; 
     299        } 
     300 
     301        debug_print(srtp_mod_cipher, "ciphertext:   %s", 
     302                    srtp_octet_string_hex_string(buffer, 
     303                                                 test_case->ciphertext_length_octets)); 
     304 
     305        /* compare the resulting ciphertext with that in the test case */ 
     306        if (len != test_case->ciphertext_length_octets) { 
     307            srtp_cipher_dealloc(c); 
     308            return srtp_err_status_algo_fail; 
     309        } 
     310        status = srtp_err_status_ok; 
     311        for (i = 0; i < test_case->ciphertext_length_octets; i++) { 
     312            if (buffer[i] != test_case->ciphertext[i]) { 
     313                status = srtp_err_status_algo_fail; 
     314                debug_print(srtp_mod_cipher, "test case %d failed", case_num); 
     315                debug_print(srtp_mod_cipher, "(failure at byte %d)", i); 
     316                break; 
     317            } 
     318        } 
     319        if (status) { 
     320 
     321            debug_print(srtp_mod_cipher, "c computed: %s", 
     322                        srtp_octet_string_hex_string(buffer, 
     323                                                     2 * test_case->plaintext_length_octets)); 
     324            debug_print(srtp_mod_cipher, "c expected: %s", 
     325                        srtp_octet_string_hex_string(test_case->ciphertext, 
     326                                                     2 * test_case->plaintext_length_octets)); 
     327 
     328            srtp_cipher_dealloc(c); 
     329            return srtp_err_status_algo_fail; 
     330        } 
     331 
     332        /* 
     333         * test the decrypt function 
     334         */ 
     335        debug_print(srtp_mod_cipher, "testing decryption", NULL); 
     336 
     337        /* re-initialize cipher for decryption */ 
     338        status = srtp_cipher_init(c, test_case->key); 
     339        if (status) { 
     340            srtp_cipher_dealloc(c); 
     341            return status; 
     342        } 
     343 
     344        /* copy ciphertext into test buffer */ 
     345        if (test_case->ciphertext_length_octets > SELF_TEST_BUF_OCTETS) { 
     346            srtp_cipher_dealloc(c); 
     347            return srtp_err_status_bad_param; 
     348        } 
     349        for (i = 0; i < test_case->ciphertext_length_octets; i++) { 
     350            buffer[i] = test_case->ciphertext[i]; 
     351        } 
     352 
     353        debug_print(srtp_mod_cipher, "ciphertext:    %s", 
     354                    srtp_octet_string_hex_string(buffer, 
     355                                                 test_case->plaintext_length_octets)); 
     356 
     357        /* set the initialization vector */ 
     358        status = srtp_cipher_set_iv(c, (uint8_t*)test_case->idx, srtp_direction_decrypt); 
     359        if (status) { 
     360            srtp_cipher_dealloc(c); 
     361            return status; 
     362        } 
     363 
     364        if (c->algorithm == SRTP_AES_GCM_128 || c->algorithm == SRTP_AES_GCM_256) { 
     365            /* 
     366             * Set the AAD 
     367             */ 
     368            status = srtp_cipher_set_aad(c, test_case->aad, test_case->aad_length_octets); 
     369            if (status) { 
     370                srtp_cipher_dealloc(c); 
     371                return status; 
     372            } 
     373            debug_print(srtp_mod_cipher, "AAD:    %s", 
     374                        srtp_octet_string_hex_string(test_case->aad, 
     375                                                     test_case->aad_length_octets)); 
     376        } 
     377 
     378        /* decrypt */ 
     379        len = test_case->ciphertext_length_octets; 
     380        status = srtp_cipher_decrypt(c, buffer, &len); 
     381        if (status) { 
     382            srtp_cipher_dealloc(c); 
     383            return status; 
     384        } 
     385 
     386        debug_print(srtp_mod_cipher, "plaintext:   %s", 
     387                    srtp_octet_string_hex_string(buffer, 
     388                                                 test_case->plaintext_length_octets)); 
     389 
     390        /* compare the resulting plaintext with that in the test case */ 
     391        if (len != test_case->plaintext_length_octets) { 
     392            srtp_cipher_dealloc(c); 
     393            return srtp_err_status_algo_fail; 
     394        } 
     395        status = srtp_err_status_ok; 
     396        for (i = 0; i < test_case->plaintext_length_octets; i++) { 
     397            if (buffer[i] != test_case->plaintext[i]) { 
     398                status = srtp_err_status_algo_fail; 
     399                debug_print(srtp_mod_cipher, "test case %d failed", case_num); 
     400                debug_print(srtp_mod_cipher, "(failure at byte %d)", i); 
     401            } 
     402        } 
     403        if (status) { 
     404 
     405            debug_print(srtp_mod_cipher, "p computed: %s", 
     406                        srtp_octet_string_hex_string(buffer, 
     407                                                     2 * test_case->plaintext_length_octets)); 
     408            debug_print(srtp_mod_cipher, "p expected: %s", 
     409                        srtp_octet_string_hex_string(test_case->plaintext, 
     410                                                     2 * test_case->plaintext_length_octets)); 
     411 
     412            srtp_cipher_dealloc(c); 
     413            return srtp_err_status_algo_fail; 
     414        } 
     415 
     416        /* deallocate the cipher */ 
     417        status = srtp_cipher_dealloc(c); 
     418        if (status) { 
     419            return status; 
     420        } 
     421 
     422        /* 
     423         * the cipher passed the test case, so move on to the next test 
     424         * case in the list; if NULL, we'l proceed to the next test 
     425         */ 
     426        test_case = test_case->next_test_case; 
     427        ++case_num; 
     428    } 
     429 
     430    /* now run some random invertibility tests */ 
     431 
     432    /* allocate cipher, using paramaters from the first test case */ 
     433    test_case = test_data; 
     434    status = srtp_cipher_type_alloc(ct, &c, test_case->key_length_octets, test_case->tag_length_octets); 
    126435    if (status) { 
    127       cipher_dealloc(c); 
    128       return status; 
    129     } 
    130      
    131     /* copy plaintext into test buffer */ 
    132     if (test_case->ciphertext_length_octets > SELF_TEST_BUF_OCTETS) { 
    133       cipher_dealloc(c);     
    134       return err_status_bad_param; 
    135     } 
    136     for (i=0; i < test_case->plaintext_length_octets; i++) 
    137       buffer[i] = test_case->plaintext[i]; 
    138  
    139     debug_print(mod_cipher, "plaintext:    %s", 
    140              octet_string_hex_string(buffer, 
    141                                      test_case->plaintext_length_octets)); 
    142  
    143     /* set the initialization vector */ 
    144     status = cipher_set_iv(c, test_case->idx, direction_encrypt); 
     436        return status; 
     437    } 
     438 
     439    for (j = 0; j < NUM_RAND_TESTS; j++) { 
     440        unsigned length; 
     441        int plaintext_len; 
     442        uint8_t key[MAX_KEY_LEN]; 
     443        uint8_t iv[MAX_KEY_LEN]; 
     444 
     445        /* choose a length at random (leaving room for IV and padding) */ 
     446        length = rand() % (SELF_TEST_BUF_OCTETS - 64); 
     447        debug_print(srtp_mod_cipher, "random plaintext length %d\n", length); 
     448        status = srtp_cipher_rand(buffer, length); 
     449        if (status) { 
     450            srtp_cipher_dealloc(c); 
     451            return status; 
     452        } 
     453 
     454        debug_print(srtp_mod_cipher, "plaintext:    %s", 
     455                    srtp_octet_string_hex_string(buffer, length)); 
     456 
     457        /* copy plaintext into second buffer */ 
     458        for (i = 0; (unsigned int)i < length; i++) { 
     459            buffer2[i] = buffer[i]; 
     460        } 
     461 
     462        /* choose a key at random */ 
     463        if (test_case->key_length_octets > MAX_KEY_LEN) { 
     464            srtp_cipher_dealloc(c); 
     465            return srtp_err_status_cant_check; 
     466        } 
     467        status = srtp_cipher_rand(key, test_case->key_length_octets); 
     468        if (status) { 
     469            srtp_cipher_dealloc(c); 
     470            return status; 
     471        } 
     472 
     473        /* chose a random initialization vector */ 
     474        status = srtp_cipher_rand(iv, MAX_KEY_LEN); 
     475        if (status) { 
     476            srtp_cipher_dealloc(c); 
     477            return status; 
     478        } 
     479 
     480        /* initialize cipher */ 
     481        status = srtp_cipher_init(c, key); 
     482        if (status) { 
     483            srtp_cipher_dealloc(c); 
     484            return status; 
     485        } 
     486 
     487        /* set initialization vector */ 
     488        status = srtp_cipher_set_iv(c, (uint8_t*)test_case->idx, srtp_direction_encrypt); 
     489        if (status) { 
     490            srtp_cipher_dealloc(c); 
     491            return status; 
     492        } 
     493 
     494        if (c->algorithm == SRTP_AES_GCM_128 || c->algorithm == SRTP_AES_GCM_256) { 
     495            /* 
     496             * Set the AAD 
     497             */ 
     498            status = srtp_cipher_set_aad(c, test_case->aad, test_case->aad_length_octets); 
     499            if (status) { 
     500                srtp_cipher_dealloc(c); 
     501                return status; 
     502            } 
     503            debug_print(srtp_mod_cipher, "AAD:    %s", 
     504                        srtp_octet_string_hex_string(test_case->aad, 
     505                                                     test_case->aad_length_octets)); 
     506        } 
     507 
     508        /* encrypt buffer with cipher */ 
     509        plaintext_len = length; 
     510        status = srtp_cipher_encrypt(c, buffer, &length); 
     511        if (status) { 
     512            srtp_cipher_dealloc(c); 
     513            return status; 
     514        } 
     515        if (c->algorithm == SRTP_AES_GCM_128 || c->algorithm == SRTP_AES_GCM_256) { 
     516            /* 
     517             * Get the GCM tag 
     518             */ 
     519            status = srtp_cipher_get_tag(c, buffer + length, &tag_len); 
     520            if (status) { 
     521                srtp_cipher_dealloc(c); 
     522                return status; 
     523            } 
     524            length += tag_len; 
     525        } 
     526        debug_print(srtp_mod_cipher, "ciphertext:   %s", 
     527                    srtp_octet_string_hex_string(buffer, length)); 
     528 
     529        /* 
     530         * re-initialize cipher for decryption, re-set the iv, then 
     531         * decrypt the ciphertext 
     532         */ 
     533        status = srtp_cipher_init(c, key); 
     534        if (status) { 
     535            srtp_cipher_dealloc(c); 
     536            return status; 
     537        } 
     538        status = srtp_cipher_set_iv(c, (uint8_t*)test_case->idx, srtp_direction_decrypt); 
     539        if (status) { 
     540            srtp_cipher_dealloc(c); 
     541            return status; 
     542        } 
     543        if (c->algorithm == SRTP_AES_GCM_128 || c->algorithm == SRTP_AES_GCM_256) { 
     544            /* 
     545             * Set the AAD 
     546             */ 
     547            status = srtp_cipher_set_aad(c, test_case->aad, test_case->aad_length_octets); 
     548            if (status) { 
     549                srtp_cipher_dealloc(c); 
     550                return status; 
     551            } 
     552            debug_print(srtp_mod_cipher, "AAD:    %s", 
     553                        srtp_octet_string_hex_string(test_case->aad, 
     554                                                     test_case->aad_length_octets)); 
     555        } 
     556        status = srtp_cipher_decrypt(c, buffer, &length); 
     557        if (status) { 
     558            srtp_cipher_dealloc(c); 
     559            return status; 
     560        } 
     561 
     562        debug_print(srtp_mod_cipher, "plaintext[2]: %s", 
     563                    srtp_octet_string_hex_string(buffer, length)); 
     564 
     565        /* compare the resulting plaintext with the original one */ 
     566        if (length != plaintext_len) { 
     567            srtp_cipher_dealloc(c); 
     568            return srtp_err_status_algo_fail; 
     569        } 
     570        status = srtp_err_status_ok; 
     571        for (i = 0; i < plaintext_len; i++) { 
     572            if (buffer[i] != buffer2[i]) { 
     573                status = srtp_err_status_algo_fail; 
     574                debug_print(srtp_mod_cipher, "random test case %d failed", case_num); 
     575                debug_print(srtp_mod_cipher, "(failure at byte %d)", i); 
     576            } 
     577        } 
     578        if (status) { 
     579            srtp_cipher_dealloc(c); 
     580            return srtp_err_status_algo_fail; 
     581        } 
     582 
     583    } 
     584 
     585    status = srtp_cipher_dealloc(c); 
    145586    if (status) { 
    146       cipher_dealloc(c); 
    147       return status; 
    148     }  
    149      
    150     if (c->algorithm == AES_128_GCM || c->algorithm == AES_256_GCM) { 
    151         debug_print(mod_cipher, "IV:    %s", 
    152                     octet_string_hex_string(test_case->idx, 12)); 
    153  
    154         /* 
    155          * Set the AAD  
    156          */ 
    157         status = cipher_set_aad(c, test_case->aad,  
    158                                 test_case->aad_length_octets); 
    159         if (status) { 
    160             cipher_dealloc(c); 
    161             return status; 
    162         }  
    163         debug_print(mod_cipher, "AAD:    %s", 
    164         octet_string_hex_string(test_case->aad,  
    165                                 test_case->aad_length_octets)); 
    166     } 
    167  
    168     /* encrypt */ 
    169     len = test_case->plaintext_length_octets; 
    170     status = cipher_encrypt(c, buffer, &len); 
    171     if (status) { 
    172       cipher_dealloc(c); 
    173       return status; 
    174     } 
    175      
    176     if (c->algorithm == AES_128_GCM || c->algorithm == AES_256_GCM) { 
    177         /* 
    178          * Get the GCM tag 
    179          */ 
    180         status = cipher_get_tag(c, buffer + len, &tag_len); 
    181         if (status) { 
    182             cipher_dealloc(c); 
    183             return status; 
    184         } 
    185         len += tag_len; 
    186     } 
    187  
    188     debug_print(mod_cipher, "ciphertext:   %s", 
    189              octet_string_hex_string(buffer, 
    190                                      test_case->ciphertext_length_octets)); 
    191  
    192     /* compare the resulting ciphertext with that in the test case */ 
    193     if (len != test_case->ciphertext_length_octets) 
    194       return err_status_algo_fail; 
    195     status = err_status_ok; 
    196     for (i=0; i < test_case->ciphertext_length_octets; i++) 
    197       if (buffer[i] != test_case->ciphertext[i]) { 
    198         status = err_status_algo_fail; 
    199         debug_print(mod_cipher, "test case %d failed", case_num); 
    200         debug_print(mod_cipher, "(failure at byte %d)", i); 
    201         break; 
    202       } 
    203     if (status) { 
    204  
    205       debug_print(mod_cipher, "c computed: %s", 
    206              octet_string_hex_string(buffer, 
    207                   2*test_case->plaintext_length_octets)); 
    208       debug_print(mod_cipher, "c expected: %s", 
    209                   octet_string_hex_string(test_case->ciphertext, 
    210                           2*test_case->plaintext_length_octets)); 
    211  
    212       cipher_dealloc(c); 
    213       return err_status_algo_fail; 
    214     } 
    215  
    216     /* 
    217      * test the decrypt function 
    218      */ 
    219     debug_print(mod_cipher, "testing decryption", NULL);     
    220  
    221     /* re-initialize cipher for decryption */ 
    222     status = cipher_init(c, test_case->key); 
    223     if (status) { 
    224       cipher_dealloc(c); 
    225       return status; 
    226     } 
    227  
    228     /* copy ciphertext into test buffer */ 
    229     if (test_case->ciphertext_length_octets > SELF_TEST_BUF_OCTETS) { 
    230       cipher_dealloc(c);     
    231       return err_status_bad_param; 
    232     } 
    233     for (i=0; i < test_case->ciphertext_length_octets; i++) 
    234       buffer[i] = test_case->ciphertext[i]; 
    235  
    236     debug_print(mod_cipher, "ciphertext:    %s", 
    237                 octet_string_hex_string(buffer, 
    238                                         test_case->plaintext_length_octets)); 
    239  
    240     /* set the initialization vector */ 
    241     status = cipher_set_iv(c, test_case->idx, direction_decrypt); 
    242     if (status) { 
    243       cipher_dealloc(c); 
    244       return status; 
    245     }  
    246      
    247     if (c->algorithm == AES_128_GCM || c->algorithm == AES_256_GCM) { 
    248         /* 
    249          * Set the AAD  
    250          */ 
    251         status = cipher_set_aad(c, test_case->aad,  
    252                                 test_case->aad_length_octets); 
    253         if (status) { 
    254             cipher_dealloc(c); 
    255             return status; 
    256         }  
    257         debug_print(mod_cipher, "AAD:    %s", 
    258                     octet_string_hex_string(test_case->aad,  
    259                                             test_case->aad_length_octets)); 
    260     } 
    261  
    262     /* decrypt */ 
    263     len = test_case->ciphertext_length_octets; 
    264     status = cipher_decrypt(c, buffer, &len); 
    265     if (status) { 
    266       cipher_dealloc(c); 
    267       return status; 
    268     } 
    269      
    270     debug_print(mod_cipher, "plaintext:   %s", 
    271              octet_string_hex_string(buffer, 
    272                                      test_case->plaintext_length_octets)); 
    273  
    274     /* compare the resulting plaintext with that in the test case */ 
    275     if (len != test_case->plaintext_length_octets) 
    276       return err_status_algo_fail; 
    277     status = err_status_ok; 
    278     for (i=0; i < test_case->plaintext_length_octets; i++) 
    279       if (buffer[i] != test_case->plaintext[i]) { 
    280         status = err_status_algo_fail; 
    281         debug_print(mod_cipher, "test case %d failed", case_num); 
    282         debug_print(mod_cipher, "(failure at byte %d)", i); 
    283       } 
    284     if (status) { 
    285  
    286       debug_print(mod_cipher, "p computed: %s", 
    287              octet_string_hex_string(buffer, 
    288                   2*test_case->plaintext_length_octets)); 
    289       debug_print(mod_cipher, "p expected: %s", 
    290                   octet_string_hex_string(test_case->plaintext, 
    291                           2*test_case->plaintext_length_octets)); 
    292  
    293       cipher_dealloc(c); 
    294       return err_status_algo_fail; 
    295     } 
    296  
    297     /* deallocate the cipher */ 
    298     status = cipher_dealloc(c); 
    299     if (status) 
    300       return status; 
    301      
    302     /*  
    303      * the cipher passed the test case, so move on to the next test 
    304      * case in the list; if NULL, we'l proceed to the next test 
    305      */    
    306     test_case = test_case->next_test_case; 
    307     ++case_num; 
    308   } 
    309    
    310   /* now run some random invertibility tests */ 
    311  
    312   /* allocate cipher, using paramaters from the first test case */ 
    313   test_case = test_data; 
    314   status = cipher_type_alloc(ct, &c, test_case->key_length_octets, test_case->tag_length_octets); 
    315   if (status) 
    316       return status; 
    317    
    318   rand_source_init(); 
    319    
    320   for (j=0; j < NUM_RAND_TESTS; j++) { 
    321     unsigned length; 
    322     int plaintext_len; 
    323     uint8_t key[MAX_KEY_LEN]; 
    324     uint8_t  iv[MAX_KEY_LEN]; 
    325  
    326     /* choose a length at random (leaving room for IV and padding) */ 
    327     length = rand() % (SELF_TEST_BUF_OCTETS - 64); 
    328     debug_print(mod_cipher, "random plaintext length %d\n", length); 
    329     status = rand_source_get_octet_string(buffer, length); 
    330     if (status) return status; 
    331  
    332     debug_print(mod_cipher, "plaintext:    %s", 
    333                 octet_string_hex_string(buffer, length)); 
    334  
    335     /* copy plaintext into second buffer */ 
    336     for (i=0; (unsigned int)i < length; i++) 
    337       buffer2[i] = buffer[i]; 
    338      
    339     /* choose a key at random */ 
    340     if (test_case->key_length_octets > MAX_KEY_LEN) 
    341       return err_status_cant_check; 
    342     status = rand_source_get_octet_string(key, test_case->key_length_octets); 
    343     if (status) return status; 
    344  
    345    /* chose a random initialization vector */ 
    346     status = rand_source_get_octet_string(iv, MAX_KEY_LEN); 
    347     if (status) return status; 
    348          
    349     /* initialize cipher */ 
    350     status = cipher_init(c, key); 
    351     if (status) { 
    352       cipher_dealloc(c); 
    353       return status; 
    354     } 
    355  
    356     /* set initialization vector */ 
    357     status = cipher_set_iv(c, test_case->idx, direction_encrypt); 
    358     if (status) { 
    359       cipher_dealloc(c); 
    360       return status; 
    361     }  
    362  
    363     if (c->algorithm == AES_128_GCM || c->algorithm == AES_256_GCM) { 
    364         /* 
    365          * Set the AAD  
    366          */ 
    367         status = cipher_set_aad(c, test_case->aad,  
    368         test_case->aad_length_octets); 
    369         if (status) { 
    370             cipher_dealloc(c); 
    371             return status; 
    372         }  
    373         debug_print(mod_cipher, "AAD:    %s", 
    374                     octet_string_hex_string(test_case->aad,  
    375                                             test_case->aad_length_octets)); 
    376     } 
    377  
    378     /* encrypt buffer with cipher */ 
    379     plaintext_len = length; 
    380     status = cipher_encrypt(c, buffer, &length); 
    381     if (status) { 
    382       cipher_dealloc(c); 
    383       return status; 
    384     } 
    385     if (c->algorithm == AES_128_GCM || c->algorithm == AES_256_GCM) { 
    386         /* 
    387          * Get the GCM tag 
    388          */ 
    389         status = cipher_get_tag(c, buffer + length, &tag_len); 
    390         if (status) { 
    391             cipher_dealloc(c); 
    392             return status; 
    393         } 
    394         length += tag_len; 
    395     } 
    396     debug_print(mod_cipher, "ciphertext:   %s", 
    397                 octet_string_hex_string(buffer, length)); 
    398  
    399     /*  
    400      * re-initialize cipher for decryption, re-set the iv, then 
    401      * decrypt the ciphertext 
    402      */ 
    403     status = cipher_init(c, key); 
    404     if (status) { 
    405       cipher_dealloc(c); 
    406       return status; 
    407     } 
    408     status = cipher_set_iv(c, test_case->idx, direction_decrypt); 
    409     if (status) { 
    410       cipher_dealloc(c); 
    411       return status; 
    412     }  
    413     if (c->algorithm == AES_128_GCM || c->algorithm == AES_256_GCM) { 
    414         /* 
    415          * Set the AAD  
    416          */ 
    417         status = cipher_set_aad(c, test_case->aad,  
    418                                 test_case->aad_length_octets); 
    419         if (status) { 
    420             cipher_dealloc(c); 
    421             return status; 
    422         }  
    423         debug_print(mod_cipher, "AAD:    %s", 
    424                     octet_string_hex_string(test_case->aad,  
    425                                             test_case->aad_length_octets)); 
    426     } 
    427     status = cipher_decrypt(c, buffer, &length); 
    428     if (status) { 
    429       cipher_dealloc(c); 
    430       return status; 
    431     }     
    432  
    433     debug_print(mod_cipher, "plaintext[2]: %s", 
    434                 octet_string_hex_string(buffer, length));     
    435  
    436     /* compare the resulting plaintext with the original one */ 
    437     if (length != plaintext_len) { 
    438       return err_status_algo_fail; 
    439     } 
    440     status = err_status_ok; 
    441     for (i=0; i < plaintext_len; i++) 
    442       if (buffer[i] != buffer2[i]) { 
    443         status = err_status_algo_fail; 
    444         debug_print(mod_cipher, "random test case %d failed", case_num); 
    445         debug_print(mod_cipher, "(failure at byte %d)", i); 
    446       } 
    447     if (status) { 
    448       cipher_dealloc(c); 
    449       return err_status_algo_fail; 
    450     } 
    451          
    452   } 
    453  
    454   status = cipher_dealloc(c); 
    455   if (status) 
    456     return status; 
    457  
    458   return err_status_ok; 
    459 } 
    460  
    461  
    462 /*  
    463  * cipher_type_self_test(ct) performs cipher_type_test on ct's internal 
     587        return status; 
     588    } 
     589 
     590    return srtp_err_status_ok; 
     591} 
     592 
     593 
     594/* 
     595 * srtp_cipher_type_self_test(ct) performs srtp_cipher_type_test on ct's internal 
    464596 * list of test data. 
    465597 */ 
    466  
    467 err_status_t 
    468 cipher_type_self_test(const cipher_type_t *ct) { 
    469   return cipher_type_test(ct, ct->test_data); 
     598srtp_err_status_t srtp_cipher_type_self_test (const srtp_cipher_type_t *ct) 
     599{ 
     600    return srtp_cipher_type_test(ct, ct->test_data); 
    470601} 
    471602 
     
    473604 * cipher_bits_per_second(c, l, t) computes (an estimate of) the 
    474605 * number of bits that a cipher implementation can encrypt in a second 
    475  *  
     606 * 
    476607 * c is a cipher (which MUST be allocated and initialized already), l 
    477608 * is the length in octets of the test data to be encrypted, and t is 
     
    480611 * if an error is encountered, the value 0 is returned 
    481612 */ 
    482  
    483 uint64_t 
    484 cipher_bits_per_second(cipher_t *c, int octets_in_buffer, int num_trials) { 
    485   int i; 
    486   v128_t nonce; 
    487   clock_t timer; 
    488   unsigned char *enc_buf; 
    489   unsigned int len = octets_in_buffer; 
    490  
    491   enc_buf = (unsigned char*) crypto_alloc(octets_in_buffer); 
    492   if (enc_buf == NULL) 
    493     return 0;  /* indicate bad parameters by returning null */ 
    494    
    495   /* time repeated trials */ 
    496   v128_set_to_zero(&nonce); 
    497   timer = clock(); 
    498   for(i=0; i < num_trials; i++, nonce.v32[3] = i) { 
    499     cipher_set_iv(c, &nonce, direction_encrypt); 
    500     cipher_encrypt(c, enc_buf, &len); 
    501   } 
    502   timer = clock() - timer; 
    503  
    504   crypto_free(enc_buf); 
    505  
    506   if (timer == 0) { 
    507     /* Too fast! */ 
    508     return 0; 
    509   } 
    510    
    511   return (uint64_t)CLOCKS_PER_SEC * num_trials * 8 * octets_in_buffer / timer; 
    512 } 
     613uint64_t srtp_cipher_bits_per_second (srtp_cipher_t *c, int octets_in_buffer, int num_trials) 
     614{ 
     615    int i; 
     616    v128_t nonce; 
     617    clock_t timer; 
     618    unsigned char *enc_buf; 
     619    unsigned int len = octets_in_buffer; 
     620 
     621    enc_buf = (unsigned char*)srtp_crypto_alloc(octets_in_buffer); 
     622    if (enc_buf == NULL) { 
     623        return 0; /* indicate bad parameters by returning null */ 
     624 
     625    } 
     626    /* time repeated trials */ 
     627    v128_set_to_zero(&nonce); 
     628    timer = clock(); 
     629    for (i = 0; i < num_trials; i++, nonce.v32[3] = i) { 
     630        if (srtp_cipher_set_iv(c, (uint8_t*)&nonce, srtp_direction_encrypt) != srtp_err_status_ok) { 
     631            srtp_crypto_free(enc_buf); 
     632            return 0; 
     633        } 
     634        if (srtp_cipher_encrypt(c, enc_buf, &len) != srtp_err_status_ok) { 
     635            srtp_crypto_free(enc_buf); 
     636            return 0; 
     637        } 
     638    } 
     639    timer = clock() - timer; 
     640 
     641    srtp_crypto_free(enc_buf); 
     642 
     643    if (timer == 0) { 
     644        /* Too fast! */ 
     645        return 0; 
     646    } 
     647 
     648    return (uint64_t)CLOCKS_PER_SEC * num_trials * 8 * octets_in_buffer / timer; 
     649} 
Note: See TracChangeset for help on using the changeset viewer.