/* * cipher_bits_per_second(c, l, t) computes (an estimate of) the * number of bits that a cipher implementation can encrypt in a second * * c is a cipher (which MUST be allocated and initialized already), l * is the length in octets of the test data to be encrypted, and t is * the number of trials * * if an error is encountered, the value 0 is returned */ uint64_t srtp_cipher_bits_per_second (srtp_cipher_t *c, int octets_in_buffer, int num_trials) { int i; v128_t nonce; clock_t timer; unsigned char *enc_buf; unsigned int len = octets_in_buffer; enc_buf = (unsigned char*)srtp_crypto_alloc(octets_in_buffer); if (enc_buf == NULL) { return 0; /* indicate bad parameters by returning null */ } /* time repeated trials */ v128_set_to_zero(&nonce); timer = clock(); for (i = 0; i < num_trials; i++, nonce.v32[3] = i) { srtp_cipher_set_iv(c, (uint8_t*)&nonce, direction_encrypt); srtp_cipher_encrypt(c, enc_buf, &len); } timer = clock() - timer; srtp_crypto_free(enc_buf); if (timer == 0) { /* Too fast! */ return 0; } return (uint64_t)CLOCKS_PER_SEC * num_trials * 8 * octets_in_buffer / timer; }
void v128_left_shift(v128_t *x, int shift) { int i; const int base_index = shift >> 5; const int bit_index = shift & 31; if (shift > 127) { v128_set_to_zero(x); return; } if (bit_index == 0) { for (i=0; i < 4 - base_index; i++) x->v32[i] = x->v32[i+base_index]; } else { for (i=0; i < 4 - base_index - 1; i++) x->v32[i] = (x->v32[i+base_index] >> bit_index) ^ (x->v32[i+base_index+1] << (32 - bit_index)); x->v32[4 - base_index-1] = x->v32[4-1] >> bit_index; } /* now wrap up the final portion */ for (i = 4 - base_index; i < 4; i++) x->v32[i] = 0; }
static srtp_err_status_t srtp_aes_icm_context_init (srtp_aes_icm_ctx_t *c, const uint8_t *key) { srtp_err_status_t status; int base_key_len, copy_len; if (c->key_size > 16 && c->key_size < 30) { /* Ismacryp */ base_key_len = 16; } else if (c->key_size == 30 || c->key_size == 38 || c->key_size == 46) { base_key_len = c->key_size - 14; } else{ return srtp_err_status_bad_param; } /* * set counter and initial values to 'offset' value, being careful not to * go past the end of the key buffer */ v128_set_to_zero(&c->counter); v128_set_to_zero(&c->offset); copy_len = c->key_size - base_key_len; /* force last two octets of the offset to be left zero (for srtp compatibility) */ if (copy_len > 14) { copy_len = 14; } memcpy(&c->counter, key + base_key_len, copy_len); memcpy(&c->offset, key + base_key_len, copy_len); debug_print(srtp_mod_aes_icm, "key: %s", srtp_octet_string_hex_string(key, base_key_len)); debug_print(srtp_mod_aes_icm, "offset: %s", v128_hex_string(&c->offset)); /* expand key */ status = srtp_aes_expand_encryption_key(key, base_key_len, &c->expanded_key); if (status) { v128_set_to_zero(&c->counter); v128_set_to_zero(&c->offset); return status; } /* indicate that the keystream_buffer is empty */ c->bytes_in_buffer = 0; return srtp_err_status_ok; }
/* * aes_icm_openssl_context_init(...) initializes the aes_icm_context * using the value in key[]. * * the key is the secret key * * the salt is unpredictable (but not necessarily secret) data which * randomizes the starting point in the keystream */ static srtp_err_status_t srtp_aes_icm_openssl_context_init (void* cv, const uint8_t *key) { srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv; const EVP_CIPHER *evp; /* * set counter and initial values to 'offset' value, being careful not to * go past the end of the key buffer */ v128_set_to_zero(&c->counter); v128_set_to_zero(&c->offset); memcpy(&c->counter, key + c->key_size, SRTP_SALT_SIZE); memcpy(&c->offset, key + c->key_size, SRTP_SALT_SIZE); /* force last two octets of the offset to zero (for srtp compatibility) */ c->offset.v8[SRTP_SALT_SIZE] = c->offset.v8[SRTP_SALT_SIZE + 1] = 0; c->counter.v8[SRTP_SALT_SIZE] = c->counter.v8[SRTP_SALT_SIZE + 1] = 0; debug_print(srtp_mod_aes_icm, "key: %s", srtp_octet_string_hex_string(key, c->key_size)); debug_print(srtp_mod_aes_icm, "offset: %s", v128_hex_string(&c->offset)); switch (c->key_size) { case SRTP_AES_256_KEYSIZE: evp = EVP_aes_256_ctr(); break; #ifndef SRTP_NO_AES192 case SRTP_AES_192_KEYSIZE: evp = EVP_aes_192_ctr(); break; #endif case SRTP_AES_128_KEYSIZE: evp = EVP_aes_128_ctr(); break; default: return srtp_err_status_bad_param; break; } if (!EVP_EncryptInit_ex(c->ctx, evp, NULL, key, NULL)) { return srtp_err_status_fail; } else { return srtp_err_status_ok; } return srtp_err_status_ok; }
static srtp_err_status_t srtp_aes_icm_context_init (void *cv, const uint8_t *key) { srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv; srtp_err_status_t status; int base_key_len, copy_len; if (c->key_size == SRTP_AES_ICM_128_KEY_LEN_WSALT || c->key_size == SRTP_AES_ICM_256_KEY_LEN_WSALT) { base_key_len = c->key_size - SRTP_SALT_LEN; } else{ return srtp_err_status_bad_param; } /* * set counter and initial values to 'offset' value, being careful not to * go past the end of the key buffer */ v128_set_to_zero(&c->counter); v128_set_to_zero(&c->offset); copy_len = c->key_size - base_key_len; /* force last two octets of the offset to be left zero (for srtp compatibility) */ if (copy_len > SRTP_SALT_LEN) { copy_len = SRTP_SALT_LEN; } memcpy(&c->counter, key + base_key_len, copy_len); memcpy(&c->offset, key + base_key_len, copy_len); debug_print(srtp_mod_aes_icm, "key: %s", srtp_octet_string_hex_string(key, base_key_len)); debug_print(srtp_mod_aes_icm, "offset: %s", v128_hex_string(&c->offset)); /* expand key */ status = srtp_aes_expand_encryption_key(key, base_key_len, &c->expanded_key); if (status) { v128_set_to_zero(&c->counter); v128_set_to_zero(&c->offset); return status; } /* indicate that the keystream_buffer is empty */ c->bytes_in_buffer = 0; return srtp_err_status_ok; }
/* * aes_icm_openssl_context_init(...) initializes the aes_icm_context * using the value in key[]. * * the key is the secret key * * the salt is unpredictable (but not necessarily secret) data which * randomizes the starting point in the keystream */ err_status_t aes_icm_openssl_context_init (aes_icm_ctx_t *c, const uint8_t *key, int len) { /* * set counter and initial values to 'offset' value, being careful not to * go past the end of the key buffer */ if (c->key_size + SALT_SIZE != len) return err_status_bad_param; v128_set_to_zero(&c->counter); v128_set_to_zero(&c->offset); memcpy(&c->counter, key + c->key_size, SALT_SIZE); memcpy(&c->offset, key + c->key_size, SALT_SIZE); /* force last two octets of the offset to zero (for srtp compatibility) */ c->offset.v8[SALT_SIZE] = c->offset.v8[SALT_SIZE + 1] = 0; c->counter.v8[SALT_SIZE] = c->counter.v8[SALT_SIZE + 1] = 0; /* copy key to be used later when CiscoSSL crypto context is created */ v128_copy_octet_string((v128_t*)&c->key, key); /* if the key is greater than 16 bytes, copy the second * half. Note, we treat AES-192 and AES-256 the same here * for simplicity. The storage location receiving the * key is statically allocated to handle a full 32 byte key * regardless of the cipher in use. */ if (c->key_size == AES_256_KEYSIZE #ifndef BORINGSSL || c->key_size == AES_192_KEYSIZE #endif ) { debug_print(mod_aes_icm, "Copying last 16 bytes of key: %s", v128_hex_string((v128_t*)(key + AES_128_KEYSIZE))); v128_copy_octet_string(((v128_t*)(&c->key.v8)) + 1, key + AES_128_KEYSIZE); } debug_print(mod_aes_icm, "key: %s", v128_hex_string((v128_t*)&c->key)); debug_print(mod_aes_icm, "offset: %s", v128_hex_string(&c->offset)); EVP_CIPHER_CTX_cleanup(&c->ctx); return err_status_ok; }
uint64_t cipher_array_bits_per_second(cipher_t *cipher_array[], int num_cipher, unsigned octets_in_buffer, int num_trials) { int i; v128_t nonce; clock_t timer; unsigned char *enc_buf; int cipher_index = rand() % num_cipher; /* Over-alloc, for NIST CBC padding */ enc_buf = crypto_alloc(octets_in_buffer+17); if (enc_buf == NULL) return 0; /* indicate bad parameters by returning null */ memset(enc_buf, 0, octets_in_buffer); /* time repeated trials */ v128_set_to_zero(&nonce); timer = clock(); for(i=0; i < num_trials; i++, nonce.v32[3] = i) { /* length parameter to cipher_encrypt is in/out -- out is total, padded * length -- so reset it each time. */ unsigned octets_to_encrypt = octets_in_buffer; /* encrypt buffer with cipher */ cipher_set_iv(cipher_array[cipher_index], &nonce, direction_encrypt); cipher_encrypt(cipher_array[cipher_index], enc_buf, &octets_to_encrypt); /* choose a cipher at random from the array*/ cipher_index = (*((uint32_t *)enc_buf)) % num_cipher; } timer = clock() - timer; free(enc_buf); if (timer == 0) { /* Too fast! */ return 0; } return (uint64_t)CLOCKS_PER_SEC * num_trials * 8 * octets_in_buffer / timer; }
uint64_t cipher_array_bits_per_second (cipher_t *cipher_array[], int num_cipher, unsigned octets_in_buffer, int num_trials) { int i; v128_t nonce; clock_t timer; unsigned char *enc_buf; int cipher_index = 0; enc_buf = crypto_alloc(octets_in_buffer); if (enc_buf == NULL) { return 0; /* indicate bad parameters by returning null */ } /* time repeated trials */ v128_set_to_zero(&nonce); timer = clock(); for (i = 0; i < num_trials; i++, nonce.v32[3] = i) { /* choose a cipher at random from the array*/ cipher_index = (*((uint32_t*)enc_buf)) % num_cipher; /* encrypt buffer with cipher */ cipher_set_iv(cipher_array[cipher_index], &nonce, direction_encrypt); cipher_encrypt(cipher_array[cipher_index], enc_buf, &octets_in_buffer); } timer = clock() - timer; free(enc_buf); if (timer == 0) { /* Too fast! */ return 0; } return CLOCKS_PER_SEC * num_trials * 8 * octets_in_buffer / timer; }
void v128_right_shift(v128_t *x, int index) { const int base_index = index >> 5; const int bit_index = index & 31; int i, from; uint32_t b; if (index > 127) { v128_set_to_zero(x); return; } if (bit_index == 0) { /* copy each word from left size to right side */ x->v32[4-1] = x->v32[4-1-base_index]; for (i=4-1; i > base_index; i--) x->v32[i-1] = x->v32[i-1-base_index]; } else { /* set each word to the "or" of the two bit-shifted words */ for (i = 4; i > base_index; i--) { from = i-1 - base_index; b = x->v32[from] << bit_index; if (from > 0) b |= x->v32[from-1] >> (32-bit_index); x->v32[i-1] = b; } } /* now wrap up the final portion */ for (i=0; i < base_index; i++) x->v32[i] = 0; }
int main (int argc, char *argv[]) { uint8_t buffer[2532]; unsigned int buf_len = 2500; int i, j; extern cipher_type_t aes_icm; #ifdef OPENSSL extern cipher_type_t aes_gcm_128_openssl; extern cipher_type_t aes_gcm_256_openssl; #endif cipher_t *c; uint8_t key[46] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }; v128_t nonce; int num_trials = 500; int num_fail; printf("statistical tests driver\n"); v128_set_to_zero(&nonce); for (i=0; i < 2500; i++) buffer[i] = 0; /* run tests */ printf("running stat_tests on all-null buffer, expecting failure\n"); printf("monobit %d\n", stat_test_monobit(buffer)); printf("poker %d\n", stat_test_poker(buffer)); printf("runs %d\n", stat_test_runs(buffer)); for (i=0; i < 2500; i++) buffer[i] = rand(); printf("running stat_tests on rand(), expecting success\n"); printf("monobit %d\n", stat_test_monobit(buffer)); printf("poker %d\n", stat_test_poker(buffer)); printf("runs %d\n", stat_test_runs(buffer)); printf("running stat_tests on AES-128-ICM, expecting success\n"); /* set buffer to cipher output */ for (i=0; i < 2500; i++) buffer[i] = 0; err_check(cipher_type_alloc(&aes_icm, &c, 30, 0)); err_check(cipher_init(c, key)); err_check(cipher_set_iv(c, &nonce, direction_encrypt)); err_check(cipher_encrypt(c, buffer, &buf_len)); /* run tests on cipher outout */ printf("monobit %d\n", stat_test_monobit(buffer)); printf("poker %d\n", stat_test_poker(buffer)); printf("runs %d\n", stat_test_runs(buffer)); printf("runs test (please be patient): "); fflush(stdout); num_fail = 0; v128_set_to_zero(&nonce); for(j=0; j < num_trials; j++) { for (i=0; i < 2500; i++) buffer[i] = 0; nonce.v32[3] = i; err_check(cipher_set_iv(c, &nonce, direction_encrypt)); err_check(cipher_encrypt(c, buffer, &buf_len)); if (stat_test_runs(buffer)) { num_fail++; } } printf("%d failures in %d tests\n", num_fail, num_trials); printf("(nota bene: a small fraction of stat_test failures does not \n" "indicate that the random source is invalid)\n"); err_check(cipher_dealloc(c)); printf("running stat_tests on AES-256-ICM, expecting success\n"); /* set buffer to cipher output */ for (i=0; i < 2500; i++) buffer[i] = 0; err_check(cipher_type_alloc(&aes_icm, &c, 46, 0)); err_check(cipher_init(c, key)); err_check(cipher_set_iv(c, &nonce, direction_encrypt)); err_check(cipher_encrypt(c, buffer, &buf_len)); /* run tests on cipher outout */ printf("monobit %d\n", stat_test_monobit(buffer)); printf("poker %d\n", stat_test_poker(buffer)); printf("runs %d\n", stat_test_runs(buffer)); printf("runs test (please be patient): "); fflush(stdout); num_fail = 0; v128_set_to_zero(&nonce); for(j=0; j < num_trials; j++) { for (i=0; i < 2500; i++) buffer[i] = 0; nonce.v32[3] = i; err_check(cipher_set_iv(c, &nonce, direction_encrypt)); err_check(cipher_encrypt(c, buffer, &buf_len)); if (stat_test_runs(buffer)) { num_fail++; } } #ifdef OPENSSL { printf("running stat_tests on AES-128-GCM, expecting success\n"); /* set buffer to cipher output */ for (i=0; i < 2500; i++) { buffer[i] = 0; } err_check(cipher_type_alloc(&aes_gcm_128_openssl, &c, AES_128_GCM_KEYSIZE_WSALT, 8)); err_check(cipher_init(c, key)); err_check(cipher_set_iv(c, &nonce, direction_encrypt)); err_check(cipher_encrypt(c, buffer, &buf_len)); /* run tests on cipher outout */ printf("monobit %d\n", stat_test_monobit(buffer)); printf("poker %d\n", stat_test_poker(buffer)); printf("runs %d\n", stat_test_runs(buffer)); fflush(stdout); num_fail = 0; v128_set_to_zero(&nonce); for(j=0; j < num_trials; j++) { for (i=0; i < 2500; i++) { buffer[i] = 0; } nonce.v32[3] = i; err_check(cipher_set_iv(c, &nonce, direction_encrypt)); err_check(cipher_encrypt(c, buffer, &buf_len)); buf_len = 2500; if (stat_test_runs(buffer)) { num_fail++; } } printf("running stat_tests on AES-256-GCM, expecting success\n"); /* set buffer to cipher output */ for (i=0; i < 2500; i++) { buffer[i] = 0; } err_check(cipher_type_alloc(&aes_gcm_256_openssl, &c, AES_256_GCM_KEYSIZE_WSALT, 16)); err_check(cipher_init(c, key)); err_check(cipher_set_iv(c, &nonce, direction_encrypt)); err_check(cipher_encrypt(c, buffer, &buf_len)); /* run tests on cipher outout */ printf("monobit %d\n", stat_test_monobit(buffer)); printf("poker %d\n", stat_test_poker(buffer)); printf("runs %d\n", stat_test_runs(buffer)); fflush(stdout); num_fail = 0; v128_set_to_zero(&nonce); for(j=0; j < num_trials; j++) { for (i=0; i < 2500; i++) { buffer[i] = 0; } nonce.v32[3] = i; err_check(cipher_set_iv(c, &nonce, direction_encrypt)); err_check(cipher_encrypt(c, buffer, &buf_len)); buf_len = 2500; if (stat_test_runs(buffer)) { num_fail++; } } } #endif printf("%d failures in %d tests\n", num_fail, num_trials); printf("(nota bene: a small fraction of stat_test failures does not \n" "indicate that the random source is invalid)\n"); err_check(cipher_dealloc(c)); return 0; }
int main (void) { /* * this program includes various and sundry tests for fundamental * datatypes. it's a grab-bag of throwaway code, retained only in * case of future problems */ int i, j; v128_t x; char *r = "The Moving Finger writes; and, having writ,\n" "Moves on: nor all thy Piety nor Wit\n" "Shall lure it back to cancel half a Line,\n" "Nor all thy Tears wash out a Word of it."; char *s = "incomplet"; print_string(r); print_string(s); byte_order(); test_hex_string_funcs(); for (j=0; j < 128; j++) { v128_set_to_zero(&x); /* x.v32[0] = (1 << j); */ v128_set_bit(&x, j); printf("%s\n", v128_bit_string(&x)); v128_clear_bit(&x, j); printf("%s\n", v128_bit_string(&x)); } printf("----------------------------------------------\n"); v128_set_to_zero(&x); for (i=0; i < 128; i++) { v128_set_bit(&x, i); } printf("%s\n", v128_bit_string(&x)); printf("----------------------------------------------\n"); v128_set_to_zero(&x); v128_set_bit(&x, 0); for (i=0; i < 128; i++) { printf("%s\n", v128_bit_string(&x)); v128_right_shift(&x, 1); } printf("----------------------------------------------\n"); v128_set_to_zero(&x); v128_set_bit(&x, 127); for (i=0; i < 128; i++) { printf("%s\n", v128_bit_string(&x)); v128_left_shift(&x, 1); } printf("----------------------------------------------\n"); for (i=0; i < 128; i++) { v128_set_to_zero(&x); v128_set_bit(&x, 127); v128_left_shift(&x, i); printf("%s\n", v128_bit_string(&x)); } printf("----------------------------------------------\n"); v128_set_to_zero(&x); for (i=0; i < 128; i+=2) { v128_set_bit(&x, i); } printf("bit_string: { %s }\n", v128_bit_string(&x)); printf("get_bit: { "); for (i=0; i < 128; i++) { if (v128_get_bit(&x, i) == 1) printf("1"); else printf("0"); } printf(" } \n"); test_bswap(); return 0; }
err_status_t rdb_init(rdb_t *rdb) { v128_set_to_zero(&rdb->bitmask); rdb->window_start = 0; return err_status_ok; }