/* * libZRTP SDK library, implements the ZRTP secure VoIP protocol. * Copyright (c) 2006-2009 Philip R. Zimmermann. All rights reserved. * Contact: http://philzimmermann.com * For licensing and other legal details, see the file zrtp_legal.c. * * Viktor Krykun * Vitaly Rozhkov */ #include "zrtp.h" #define _ZTU_ "zrtp cipher" typedef struct zrtp_aes_cfb_ctx { uint8_t mode; aes_encrypt_ctx aes_ctx[1]; zrtp_v128_t iv; } zrtp_aes_cfb_ctx_t; typedef struct zrtp_aes_ctr_ctx { uint8_t mode; aes_encrypt_ctx aes_ctx[1]; zrtp_v128_t salt; zrtp_v128_t counter; }zrtp_aes_ctr_ctx_t; /*===========================================================================*/ /* Global AES functions */ /*===========================================================================*/ /*---------------------------------------------------------------------------*/ zrtp_status_t zrtp_aes_cfb_stop(zrtp_cipher_t *self, void *cipher_ctx) { zrtp_memset(cipher_ctx, 0, sizeof(zrtp_aes_cfb_ctx_t)); zrtp_sys_free(cipher_ctx); return zrtp_status_ok; } zrtp_status_t zrtp_aes_ctr_stop(zrtp_cipher_t *self, void *cipher_ctx) { zrtp_memset(cipher_ctx, 0, sizeof(zrtp_aes_ctr_ctx_t)); zrtp_sys_free(cipher_ctx); return zrtp_status_ok; } zrtp_status_t zrtp_aes_stop(zrtp_cipher_t *self, void *cipher_ctx) { zrtp_status_t res; zrtp_cipher_mode_t *mode = (zrtp_cipher_mode_t*)cipher_ctx; switch (mode->mode) { case ZRTP_CIPHER_MODE_CTR: res = zrtp_aes_ctr_stop(self, cipher_ctx); break; case ZRTP_CIPHER_MODE_CFB: res = zrtp_aes_cfb_stop(self, cipher_ctx); break; default: res = zrtp_status_bad_param; break; } return res; } /*---------------------------------------------------------------------------*/ zrtp_status_t zrtp_aes_cfb_set_iv(zrtp_cipher_t *self, void* cipher_ctx, zrtp_v128_t *iv) { zrtp_aes_cfb_ctx_t* ctx = (zrtp_aes_cfb_ctx_t*)cipher_ctx; zrtp_memcpy(&ctx->iv, iv, sizeof(zrtp_v128_t)); /* clear previous context except the first byte (key length) */ zrtp_bg_aes_mode_reset(ctx->aes_ctx); return zrtp_status_ok; } zrtp_status_t zrtp_aes_ctr_set_iv(zrtp_cipher_t *self, void *cipher_ctx, zrtp_v128_t *iv ) { zrtp_aes_ctr_ctx_t* ctx = (zrtp_aes_ctr_ctx_t*)cipher_ctx; zrtp_v128_xor(&ctx->counter, &ctx->salt, iv); /* clear previous context except the first byte (key length) */ zrtp_bg_aes_mode_reset(ctx->aes_ctx); return zrtp_status_ok; } zrtp_status_t zrtp_aes_set_iv(zrtp_cipher_t *self, void *cipher_ctx, zrtp_v128_t *iv ) { zrtp_status_t res; zrtp_cipher_mode_t *mode = (zrtp_cipher_mode_t*)cipher_ctx; switch (mode->mode) { case ZRTP_CIPHER_MODE_CTR: res = zrtp_aes_ctr_set_iv(self, cipher_ctx, iv); break; case ZRTP_CIPHER_MODE_CFB: res = zrtp_aes_cfb_set_iv(self, cipher_ctx, iv); break; default: res = zrtp_status_bad_param; break; } return res; } /*---------------------------------------------------------------------------*/ zrtp_status_t zrtp_aes_cfb_encrypt( zrtp_cipher_t *self, void* cipher_ctx, unsigned char *buf, int len) { zrtp_aes_cfb_ctx_t* ctx = (zrtp_aes_cfb_ctx_t*)cipher_ctx; AES_RETURN res = zrtp_bg_aes_cfb_encrypt(buf, buf, len, ctx->iv.v8, ctx->aes_ctx); return (EXIT_SUCCESS == res) ? zrtp_status_ok : zrtp_status_cipher_fail; } void zrtp_aes_ctr_inc(unsigned char *counter) { if(!(++counter[15])) { ++counter[14]; } } zrtp_status_t zrtp_aes_ctr_encrypt( zrtp_cipher_t *self, void *cipher_ctx, unsigned char *buf, int len ) { zrtp_aes_ctr_ctx_t* ctx = (zrtp_aes_ctr_ctx_t*)cipher_ctx; AES_RETURN res = zrtp_bg_aes_ctr_crypt(buf, buf, len, ctx->counter.v8, zrtp_aes_ctr_inc, ctx->aes_ctx); return (EXIT_SUCCESS == res) ? zrtp_status_ok : zrtp_status_cipher_fail; } zrtp_status_t zrtp_aes_encrypt( zrtp_cipher_t *self, void *cipher_ctx, unsigned char *buf, int len) { zrtp_status_t res; zrtp_cipher_mode_t* mode = (zrtp_cipher_mode_t*)cipher_ctx; switch (mode->mode) { case ZRTP_CIPHER_MODE_CTR: res = zrtp_aes_ctr_encrypt(self, cipher_ctx, buf, len); break; case ZRTP_CIPHER_MODE_CFB: res = zrtp_aes_cfb_encrypt(self, cipher_ctx, buf, len); break; default: res = zrtp_status_bad_param; break; } return res; } /*---------------------------------------------------------------------------*/ zrtp_status_t zrtp_aes_cfb_decrypt( zrtp_cipher_t *self, void* cipher_ctx, unsigned char *buf, int len) { zrtp_aes_cfb_ctx_t* ctx = (zrtp_aes_cfb_ctx_t*)cipher_ctx; AES_RETURN res = zrtp_bg_aes_cfb_decrypt(buf, buf, len, ctx->iv.v8, ctx->aes_ctx); return (EXIT_SUCCESS == res) ? zrtp_status_ok : zrtp_status_cipher_fail; } zrtp_status_t zrtp_aes_ctr_decrypt( zrtp_cipher_t *self, void *cipher_ctx, unsigned char *buf, int len) { zrtp_aes_ctr_ctx_t* ctx = (zrtp_aes_ctr_ctx_t*)cipher_ctx; AES_RETURN res = zrtp_bg_aes_ctr_crypt(buf, buf, len, ctx->counter.v8, zrtp_aes_ctr_inc, ctx->aes_ctx); return (EXIT_SUCCESS == res) ? zrtp_status_ok : zrtp_status_cipher_fail; } zrtp_status_t zrtp_aes_decrypt( zrtp_cipher_t *self, void *cipher_ctx, unsigned char *buf, int len) { zrtp_status_t res; zrtp_cipher_mode_t *mode = (zrtp_cipher_mode_t*)cipher_ctx; switch(mode->mode){ case ZRTP_CIPHER_MODE_CTR: res = zrtp_aes_ctr_decrypt(self, cipher_ctx, buf, len); break; case ZRTP_CIPHER_MODE_CFB: res = zrtp_aes_cfb_decrypt(self, cipher_ctx, buf, len); break; default: res = zrtp_status_bad_param; break; } return res; } /*===========================================================================*/ /* AES 128 implementation */ /*===========================================================================*/ /*---------------------------------------------------------------------------*/ void *zrtp_aes_cfb128_start(zrtp_cipher_t *self, void *key, void *extra_data) { zrtp_aes_cfb_ctx_t *cipher_ctx = zrtp_sys_alloc(sizeof(zrtp_aes_cfb_ctx_t)); if(NULL == cipher_ctx) { return NULL; } cipher_ctx->mode = ZRTP_CIPHER_MODE_CFB; zrtp_bg_aes_encrypt_key128(((zrtp_v128_t*)key)->v8, cipher_ctx->aes_ctx); return cipher_ctx; } void *zrtp_aes_ctr128_start( zrtp_cipher_t *self, void *key, void *extra_data) { zrtp_aes_ctr_ctx_t *cipher_ctx = zrtp_sys_alloc(sizeof(zrtp_aes_ctr_ctx_t)); if(NULL == cipher_ctx) { return NULL; } cipher_ctx->mode = ZRTP_CIPHER_MODE_CTR; zrtp_memcpy(&cipher_ctx->salt, extra_data, sizeof(zrtp_v128_t)-2); cipher_ctx->salt.v8[14] = cipher_ctx->salt.v8[15] =0; zrtp_memset(&cipher_ctx->counter, 0, sizeof(zrtp_v128_t)); zrtp_bg_aes_encrypt_key128(((zrtp_v128_t*)key)->v8, cipher_ctx->aes_ctx); return cipher_ctx; } void *zrtp_aes128_start( zrtp_cipher_t *self, void *key, void *extra_data, uint8_t mode) { void *ctx; switch (mode) { case ZRTP_CIPHER_MODE_CTR: ctx = zrtp_aes_ctr128_start(self, key, extra_data); break; case ZRTP_CIPHER_MODE_CFB: ctx = zrtp_aes_cfb128_start(self, key, extra_data); break; default: ctx = NULL; break; }; return ctx; } /*---------------------------------------------------------------------------*/ /* Global CFB Test-Vectors */ static uint8_t aes_cfb_test_key[32] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }; static uint8_t aes_cfb_test_iv[16] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; static uint8_t aes_cfb_test_buf1a[50] = { 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30, 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a }; static uint8_t aes_cfb_test_buf1b[50]; //static uint8_t aes_cfb_test_buf1c[50]; static uint8_t aes_cfb_test_buf2a[50] = { 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf, 0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 }; static uint8_t aes_cfb_test_buf2b[50]; static uint8_t aes_cfb_test_key3[32]; static uint8_t aes_cfb_test_iv3[16]; static uint8_t aes_cfb_test_buf3a[50]; static uint8_t aes_cfb_test_buf3b[50] = { 0x66, 0xe9, 0x4b, 0xd4, 0xef, 0x8a, 0x2c, 0x3b, 0x88, 0x4c, 0xfa, 0x59, 0xca, 0x34, 0x2b, 0x2e, 0xf7, 0x95, 0xbd, 0x4a, 0x52, 0xe2, 0x9e, 0xd7, 0x13, 0xd3, 0x13, 0xfa, 0x20, 0xe9, 0x8d, 0xbc, 0xa1, 0x0c, 0xf6, 0x6d, 0x0f, 0xdd, 0xf3, 0x40, 0x53, 0x70, 0xb4, 0xbf, 0x8d, 0xf5, 0xbf, 0xb3, 0x47, 0xc7 }; uint8_t aes_cfb_test_buf3c[50] = { 0xdc, 0x95, 0xc0, 0x78, 0xa2, 0x40, 0x89, 0x89, 0xad, 0x48, 0xa2, 0x14, 0x92, 0x84, 0x20, 0x87, 0x08, 0xc3, 0x74, 0x84, 0x8c, 0x22, 0x82, 0x33, 0xc2, 0xb3, 0x4f, 0x33, 0x2b, 0xd2, 0xe9, 0xd3, 0x8b, 0x70, 0xc5, 0x15, 0xa6, 0x66, 0x3d, 0x38, 0xcd, 0xb8, 0xe6, 0x53, 0x2b, 0x26, 0x64, 0x91, 0x5d, 0x0d }; /* Global CTR Test-Vectors */ uint8_t aes_ctr_test_nonce[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; /* 258-bit AES CTR Test-Vectors */ uint8_t aes_ctr_test_key256[48] = { 0x00, 0x01, 0x02, 0x03, 0x05, 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0C, 0x0D, 0x0F, 0x10, 0x11, 0x12, 0x14, 0x15, 0x16, 0x17, 0x19, 0x1A, 0x1B, 0x1C, 0x1E, 0x1F, 0x20, 0x21, 0x23, 0x24, 0x25, 0x26, 0x83, 0x4E, 0xAD, 0xFC, 0xCA, 0xC7, 0xE1, 0xB3, 0x06, 0x64, 0xB1, 0xAB, 0xA4, 0x48, 0x15, 0xAB }; uint8_t aes_ctr_test_plaintext256[16] = { 0x83, 0x4E, 0xAD, 0xFC, 0xCA, 0xC7, 0xE1, 0xB3, 0x06, 0x64, 0xB1, 0xAB, 0xA4, 0x48, 0x15, 0xAB }; uint8_t aes_ctr_test_ciphertext256[16] = { 0x5d, 0x8e, 0xfd, 0xe6, 0x69, 0x62, 0xbf, 0x49, 0xda, 0xe2, 0xea, 0xcf, 0x0b, 0x69, 0xe4, 0xf6 }; /* 128-bit AES CFB Test-Vectors */ uint8_t aes_ctr_test_key128[32] = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0x00, 0x00 }; uint8_t aes_ctr_test_plaintext128[32] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; uint8_t aes_ctr_test_ciphertext128[32] = { 0xe0, 0x3e, 0xad, 0x09, 0x35, 0xc9, 0x5e, 0x80, 0xe1, 0x66, 0xb1, 0x6d, 0xd9, 0x2b, 0x4e, 0xb4, 0xd2, 0x35, 0x13, 0x16, 0x2b, 0x02, 0xd0, 0xf7, 0x2a, 0x43, 0xa2, 0xfe, 0x4a, 0x5f, 0x97, 0xab }; zrtp_status_t zrtp_aes_cfb128_self_test(zrtp_cipher_t *self) { zrtp_status_t err = zrtp_status_fail; int i = 0; zrtp_v128_t tmp_iv; zrtp_aes_cfb_ctx_t *ctx = (zrtp_aes_cfb_ctx_t*)self->start( self, aes_cfb_test_key, NULL, ZRTP_CIPHER_MODE_CFB); if(NULL == ctx) { return zrtp_status_fail; } ZRTP_LOG(3, (_ZTU_,"128 bit AES CFB\n")); ZRTP_LOG(3, (_ZTU_,"1st test...\n")); zrtp_memcpy(aes_cfb_test_buf1b, aes_cfb_test_buf1a, sizeof(aes_cfb_test_buf1a)); zrtp_memcpy(&tmp_iv, aes_cfb_test_iv, sizeof(aes_cfb_test_iv)); self->set_iv(self, ctx, &tmp_iv); ZRTP_LOG(3, (_ZTU_,"\tencryption... ")); err = self->encrypt(self, ctx, aes_cfb_test_buf1b, sizeof(aes_cfb_test_buf1b)); if (zrtp_status_ok != err) { ZRTP_LOGC(1, ("ERROR! 128-bit AES CFB encrypt returns error %d\n", err)); self->stop(self, ctx); return err; } for (i=0; i<16; i++) { if (aes_cfb_test_buf1b[i] != 0x00) { ZRTP_LOGC(1, ("ERROR! 128-bit AES CFB failed on encrypt test")); self->stop(self, ctx); return zrtp_status_fail; } } ZRTP_LOGC(3, ("OK\n")); ZRTP_LOG(3, (_ZTU_,"\tdecryption... ")); zrtp_memcpy(&tmp_iv, aes_cfb_test_iv, sizeof(aes_cfb_test_iv)); self->set_iv(self, ctx, &tmp_iv); err = self->decrypt(self, ctx, aes_cfb_test_buf1b, sizeof(aes_cfb_test_buf1b)); if (zrtp_status_ok != err) { ZRTP_LOGC(3, ("ERROR! 128-bit AES CFB decrypt returns error %d\n", err)); self->stop(self, ctx); return err; } for (i=0; istop(self, ctx); return zrtp_status_fail; } } self->stop(self, ctx); ZRTP_LOGC(3, ("OK\n")); ZRTP_LOG(3, (_ZTU_, "2nd test...\n")); ctx = self->start(self, aes_cfb_test_key3, NULL, ZRTP_CIPHER_MODE_CFB); if (NULL == ctx) { return zrtp_status_fail; } ZRTP_LOG(3, (_ZTU_, "\tencryption... ")); zrtp_memcpy(&tmp_iv, aes_cfb_test_iv3, sizeof(tmp_iv)); self->set_iv(self, ctx, &tmp_iv); err = self->encrypt(self, ctx, aes_cfb_test_buf3a, sizeof(aes_cfb_test_buf3a)); if (zrtp_status_ok != err) { ZRTP_LOGC(1, ("ERROR! 128-bit AES CFB encrypt returns error %d\n", err)); self->stop(self, ctx); return err; } for (i=0; istop(self, ctx); return zrtp_status_fail; } } ZRTP_LOGC(3, ("OK\n")); ZRTP_LOG(3, (_ZTU_, "\tdecryption... ")); zrtp_memcpy(&tmp_iv, aes_cfb_test_iv3, sizeof(tmp_iv)); self->set_iv(self, ctx, &tmp_iv); err = self->decrypt(self, ctx, aes_cfb_test_buf3b, sizeof(aes_cfb_test_buf3b)); if (zrtp_status_ok != err) { ZRTP_LOGC(1, ("ERROR! 128-bit AES CFB decrypt returns error %d\n", err)); self->stop(self, ctx); return err; } for (i=0; istop(self, ctx); return zrtp_status_fail; } } ZRTP_LOGC(3, ("OK\n")); self->stop(self, ctx); return zrtp_status_ok; } zrtp_status_t zrtp_aes_ctr128_self_test(zrtp_cipher_t *self) { uint8_t tmp_buf[32]; zrtp_status_t err = zrtp_status_fail; int i; zrtp_aes_ctr_ctx_t *ctx = (zrtp_aes_ctr_ctx_t*)self->start( self, aes_ctr_test_key128, aes_ctr_test_key128+16, ZRTP_CIPHER_MODE_CTR); if (NULL == ctx) { return zrtp_status_fail; } ZRTP_LOG(3, (_ZTU_,"128 bit AES CTR\n")); ZRTP_LOG(3, (_ZTU_, "1st test...\n")); ZRTP_LOG(3, (_ZTU_, "\tencryption... ")); self->set_iv(self, ctx, (zrtp_v128_t*)aes_ctr_test_nonce); zrtp_memcpy(tmp_buf, aes_ctr_test_plaintext128, sizeof(tmp_buf)); err = self->encrypt(self, ctx, tmp_buf, sizeof(tmp_buf)); if (zrtp_status_ok != err) { ZRTP_LOGC(1, ("ERROR! 128-bit encrypt returns error %d\n", err)); self->stop(self, ctx); return zrtp_status_fail; } for (i=0; istop(self, ctx); return err; } } ZRTP_LOGC(3, ("OK\n")); ZRTP_LOG(3, (_ZTU_, "\tdecryption...")); self->set_iv(self, ctx, (zrtp_v128_t*)aes_ctr_test_nonce); err = self->decrypt(self, ctx, tmp_buf, sizeof(tmp_buf)); if (zrtp_status_ok != err) { ZRTP_LOGC(1, ("ERROR! 128-bit AES CTR decrypt returns error %d\n", err)); self->stop(self, ctx); return err; } for (i=0; istop(self, ctx); return zrtp_status_fail; } } self->stop(self, ctx); ZRTP_LOGC(3, ("OK\n")); return zrtp_status_ok; } zrtp_status_t zrtp_aes128_self_test(zrtp_cipher_t *self, uint8_t mode) { zrtp_status_t res; switch(mode){ case ZRTP_CIPHER_MODE_CTR: res = zrtp_aes_ctr128_self_test(self); break; case ZRTP_CIPHER_MODE_CFB: res = zrtp_aes_cfb128_self_test(self); break; default: res = zrtp_status_bad_param; break; } return res; } /*===========================================================================*/ /* AES 256 implementation */ /*===========================================================================*/ /*---------------------------------------------------------------------------*/ void *zrtp_aes_cfb256_start(zrtp_cipher_t *self, void *key, void *extra_data) { zrtp_aes_cfb_ctx_t *cipher_ctx = zrtp_sys_alloc(sizeof(zrtp_aes_cfb_ctx_t)); if(NULL == cipher_ctx) { return NULL; } cipher_ctx->mode = ZRTP_CIPHER_MODE_CFB; zrtp_bg_aes_encrypt_key256(((zrtp_v256_t*)key)->v8, cipher_ctx->aes_ctx); return cipher_ctx; } void *zrtp_aes_ctr256_start(zrtp_cipher_t *self, void *key, void *extra_data) { zrtp_aes_ctr_ctx_t *cipher_ctx = zrtp_sys_alloc(sizeof(zrtp_aes_ctr_ctx_t)); if(NULL == cipher_ctx) { return NULL; } cipher_ctx->mode = ZRTP_CIPHER_MODE_CTR; zrtp_memcpy(&cipher_ctx->salt, extra_data, sizeof(zrtp_v128_t)-2); cipher_ctx->salt.v8[14] = cipher_ctx->salt.v8[15] =0; zrtp_memset(&cipher_ctx->counter, 0, sizeof(zrtp_v128_t)); zrtp_bg_aes_encrypt_key256(((zrtp_v256_t*)key)->v8, cipher_ctx->aes_ctx); return cipher_ctx; } void *zrtp_aes256_start(zrtp_cipher_t *self, void *key, void *extra_data, uint8_t mode) { void *ctx = NULL; switch (mode) { case ZRTP_CIPHER_MODE_CTR: ctx = zrtp_aes_ctr256_start(self, key, extra_data); break; case ZRTP_CIPHER_MODE_CFB: ctx = zrtp_aes_cfb256_start(self, key, extra_data); break; default: ctx = NULL; break; } return ctx; } /*---------------------------------------------------------------------------*/ zrtp_status_t zrtp_aes_cfb256_self_test(zrtp_cipher_t *self) { zrtp_status_t err; int i; zrtp_v128_t tmp_iv; zrtp_aes_cfb_ctx_t *ctx = (zrtp_aes_cfb_ctx_t*)self->start( self, aes_cfb_test_key, NULL, ZRTP_CIPHER_MODE_CFB); if (NULL == ctx) { return zrtp_status_fail; } ZRTP_LOG(3, (_ZTU_,"256 bit AES CFB\n")); ZRTP_LOG(3, (_ZTU_, "1st test...\n")); zrtp_memcpy(aes_cfb_test_buf2b, aes_cfb_test_buf2a, sizeof(aes_cfb_test_buf2a)); zrtp_memcpy(&tmp_iv, aes_cfb_test_iv, sizeof(tmp_iv)); ZRTP_LOG(3, (_ZTU_, "\tencryption... ")); self->set_iv(self, ctx, &tmp_iv); err = self->encrypt(self, ctx, aes_cfb_test_buf2b, sizeof(aes_cfb_test_buf2b)); if (zrtp_status_ok != err) { ZRTP_LOGC(1, ("ERROR! 256-bit AES CFB encrypt returns error %d\n", err)); self->stop(self, ctx); return err; } for (i=0; i<16; i++) { if (aes_cfb_test_buf2b[i] != 0x00) { ZRTP_LOGC(1, ("ERROR! 256-bit AES CFB failed on encrypt test\n")); self->stop(self, ctx); return zrtp_status_fail; } } ZRTP_LOGC(3, ("OK\n")); ZRTP_LOG(3, (_ZTU_, "\tdecryption... ")); zrtp_memcpy(&tmp_iv, aes_cfb_test_iv, sizeof(tmp_iv)); self->set_iv(self, ctx, &tmp_iv); err = self->decrypt(self, ctx, aes_cfb_test_buf2b, sizeof(aes_cfb_test_buf2b)); if (zrtp_status_ok != err) { ZRTP_LOGC(1, ("ERROR! 256-bit AES CFB decrypt returns error %d\n", err)); self->stop(self, ctx); return err; } for (i=0; istop(self, ctx); return zrtp_status_fail; } } self->stop(self, ctx); ZRTP_LOGC(3, ("OK\n")); ZRTP_LOG(3, (_ZTU_, "2nd test...\n")); ctx = self->start(self, aes_cfb_test_key3, NULL, ZRTP_CIPHER_MODE_CFB); if(NULL == ctx){ return zrtp_status_fail; } ZRTP_LOG(3, (_ZTU_, "\tencryption...")); zrtp_memset (aes_cfb_test_buf3a, 0, sizeof(aes_cfb_test_buf3a)); zrtp_memcpy(&tmp_iv, aes_cfb_test_iv3, sizeof(tmp_iv)); self->set_iv(self, ctx, &tmp_iv); err = self->encrypt(self, ctx, aes_cfb_test_buf3a, sizeof(aes_cfb_test_buf3a)); if (zrtp_status_ok != err) { ZRTP_LOGC(1, ("ERROR! 256-bit AES CFB encrypt returns error %d\n", err)); self->stop(self, ctx); return err; } for (i=0; istop(self, ctx); return zrtp_status_fail; } } ZRTP_LOGC(3, ("OK\n")); ZRTP_LOG(3, (_ZTU_, "\tdecryption...")); zrtp_memcpy(&tmp_iv, aes_cfb_test_iv3, sizeof(tmp_iv)); self->set_iv(self, ctx, &tmp_iv); err = self->decrypt(self, ctx, aes_cfb_test_buf3c, sizeof(aes_cfb_test_buf3c)); if (zrtp_status_ok != err) { ZRTP_LOGC(1, ("ERROR! 256-bit AES CFB decrypt returns error %d\n", err)); self->stop(self, ctx); return err; } for (i=0; istop(self, ctx); return zrtp_status_fail; } } self->stop(self, ctx); ZRTP_LOGC(3, ("OK\n")); return zrtp_status_ok; } zrtp_status_t zrtp_aes_ctr256_self_test(zrtp_cipher_t *self) { uint8_t tmp_buf[32]; zrtp_status_t err = zrtp_status_fail; int i; zrtp_aes_ctr_ctx_t *ctx = (zrtp_aes_ctr_ctx_t*)self->start( self, aes_ctr_test_key256, aes_ctr_test_key256+32, ZRTP_CIPHER_MODE_CTR); if (NULL == ctx) { return zrtp_status_fail; } ZRTP_LOG(3, (_ZTU_,"256 bit AES CTR\n")); ZRTP_LOG(3, (_ZTU_, "1st test...\n")); ZRTP_LOG(3, (_ZTU_, "\tencryption... ")); self->set_iv(self, ctx, (zrtp_v128_t*)aes_ctr_test_nonce); zrtp_memcpy(tmp_buf, aes_ctr_test_plaintext256, sizeof(aes_ctr_test_plaintext256)); err = self->encrypt(self, ctx, tmp_buf, sizeof(aes_ctr_test_plaintext256)); if (zrtp_status_ok != err) { ZRTP_LOGC(1, ("ERROR! 256-bit encrypt returns error %d\n", err)); self->stop(self, ctx); return zrtp_status_fail; } for (i=0; istop(self, ctx); return err; } } ZRTP_LOGC(3, ("OK\n")); ZRTP_LOG(3, (_ZTU_, "\tdecryption...")); self->set_iv(self, ctx, (zrtp_v128_t*)aes_ctr_test_nonce); err = self->decrypt(self, ctx, tmp_buf, sizeof(tmp_buf)); if (zrtp_status_ok != err) { ZRTP_LOGC(1, ("ERROR! 256-bit AES CTR decrypt returns error %d\n", err)); self->stop(self, ctx); return err; } for (i=0; istop(self, ctx); return zrtp_status_fail; } } self->stop(self, ctx); ZRTP_LOGC(3, ("OK\n")); return zrtp_status_ok; } zrtp_status_t zrtp_aes256_self_test(zrtp_cipher_t *self, uint8_t mode) { zrtp_status_t res; switch (mode) { case ZRTP_CIPHER_MODE_CTR: res = zrtp_aes_ctr256_self_test(self); break; case ZRTP_CIPHER_MODE_CFB: res = zrtp_aes_cfb256_self_test(self); break; default: res = zrtp_status_bad_param; break; } return res; } /*---------------------------------------------------------------------------*/ zrtp_status_t zrtp_defaults_aes_cipher(zrtp_global_t* global_ctx) { zrtp_cipher_t* cipher_aes128 = zrtp_sys_alloc(sizeof(zrtp_cipher_t)); zrtp_cipher_t* cipher_aes256 = zrtp_sys_alloc(sizeof(zrtp_cipher_t)); if (!cipher_aes128 || !cipher_aes256) { if (cipher_aes128) { zrtp_sys_free(cipher_aes128); } if (cipher_aes256) { zrtp_sys_free(cipher_aes256); } return zrtp_status_alloc_fail; } zrtp_memset(cipher_aes128, 0, sizeof(zrtp_cipher_t)); zrtp_memset(cipher_aes256, 0, sizeof(zrtp_cipher_t)); zrtp_memcpy(cipher_aes128->base.type, ZRTP_AES1, ZRTP_COMP_TYPE_SIZE); cipher_aes128->base.id = ZRTP_CIPHER_AES128; cipher_aes128->base.zrtp = global_ctx; cipher_aes128->start = zrtp_aes128_start; cipher_aes128->set_iv = zrtp_aes_set_iv; cipher_aes128->encrypt = zrtp_aes_encrypt; cipher_aes128->decrypt = zrtp_aes_decrypt; cipher_aes128->self_test = zrtp_aes128_self_test; cipher_aes128->stop = zrtp_aes_stop; zrtp_memcpy(cipher_aes256->base.type, ZRTP_AES3, ZRTP_COMP_TYPE_SIZE); cipher_aes256->base.id = ZRTP_CIPHER_AES256; cipher_aes256->base.zrtp = global_ctx; cipher_aes256->start = zrtp_aes256_start; cipher_aes256->set_iv = zrtp_aes_set_iv; cipher_aes256->encrypt = zrtp_aes_encrypt; cipher_aes256->decrypt = zrtp_aes_decrypt; cipher_aes256->self_test = zrtp_aes256_self_test; cipher_aes256->stop = zrtp_aes_stop; zrtp_comp_register(ZRTP_CC_CIPHER, cipher_aes128, global_ctx); zrtp_comp_register(ZRTP_CC_CIPHER, cipher_aes256, global_ctx); return zrtp_status_ok; }