From de0d7d8778c704a188d6c2cff0f0b7e076589fce Mon Sep 17 00:00:00 2001 From: bg Date: Mon, 8 Feb 2010 01:16:12 +0000 Subject: [PATCH] adding eax-mode --- bcal-cmac.c | 32 ++++++-- bcal-cmac.h | 4 +- bcal-eax.c | 118 +++++++++++++++++++++++++++++ bcal-eax.h | 53 +++++++++++++ mkfiles/aes.mk | 5 +- mkfiles/aes_c.mk | 7 +- test_src/main-aes-test.c | 159 +++++++++++++++++++++++++++++++++++++++ 7 files changed, 365 insertions(+), 13 deletions(-) create mode 100644 bcal-eax.c create mode 100644 bcal-eax.h diff --git a/bcal-cmac.c b/bcal-cmac.c index 94534d8..abc9dfa 100644 --- a/bcal-cmac.c +++ b/bcal-cmac.c @@ -59,6 +59,10 @@ uint8_t bcal_cmac_init(const bcdesc_t* desc, const void* key, uint16_t keysize_b if(ctx->k2==NULL){ return 0x16; } + ctx->lastblock = malloc(ctx->blocksize_B); + if(ctx->lastblock==NULL){ + return 0x17; + } r = bcal_cipher_init(desc, key, keysize_b, &(ctx->cctx)); if(r){ return r; @@ -79,6 +83,7 @@ uint8_t bcal_cmac_init(const bcdesc_t* desc, const void* key, uint16_t keysize_b if(left_shift_be_block(ctx->k2, ctx->blocksize_B)){ ctx->k2[ctx->blocksize_B-1] ^= r; } + ctx->last_set=0; return 0; } @@ -90,25 +95,38 @@ void bcal_cmac_free(bcal_cmac_ctx_t* ctx){ } void bcal_cmac_nextBlock (bcal_cmac_ctx_t* ctx, const void* block){ - memxor(ctx->accu, block, ctx->blocksize_B); - bcal_cipher_enc(ctx->accu, &(ctx->cctx)); + if(ctx->last_set){ + memxor(ctx->accu, ctx->lastblock, ctx->blocksize_B); + bcal_cipher_enc(ctx->accu, &(ctx->cctx)); + } + memcpy(ctx->lastblock, block, ctx->blocksize_B); + ctx->last_set=1; } void bcal_cmac_lastBlock(bcal_cmac_ctx_t* ctx, const void* block, uint16_t length_b){ uint16_t blocksize_b; blocksize_b = ctx->blocksize_B*8; - while(length_b>blocksize_b){ + while(length_b>=blocksize_b){ bcal_cmac_nextBlock(ctx, block); block = (uint8_t*)block + ctx->blocksize_B; length_b -= blocksize_b; } - memxor(ctx->accu, block, (length_b+7)/8); - if(length_b==blocksize_b){ - memxor(ctx->accu, ctx->k1, ctx->blocksize_B); - }else{ + if(ctx->last_set==0){ + memxor(ctx->accu, block, (length_b+7)/8); memxor(ctx->accu, ctx->k2, ctx->blocksize_B); ctx->accu[length_b/8] ^= 0x80>>(length_b&7); + }else{ + if(length_b==0){ + memxor(ctx->accu, ctx->lastblock, ctx->blocksize_B); + memxor(ctx->accu, ctx->k1, ctx->blocksize_B); + }else{ + memxor(ctx->accu, ctx->lastblock, ctx->blocksize_B); + bcal_cipher_enc(ctx->accu, &(ctx->cctx)); + memxor(ctx->accu, block, (length_b+7)/8); + memxor(ctx->accu, ctx->k2, ctx->blocksize_B); + ctx->accu[length_b/8] ^= 0x80>>(length_b&7); + } } bcal_cipher_enc(ctx->accu, &(ctx->cctx)); } diff --git a/bcal-cmac.h b/bcal-cmac.h index 1d4230a..be699b6 100644 --- a/bcal-cmac.h +++ b/bcal-cmac.h @@ -30,6 +30,8 @@ typedef struct{ uint8_t* accu; uint8_t* k1; uint8_t* k2; + uint8_t* lastblock; + uint8_t last_set; uint8_t blocksize_B; } bcal_cmac_ctx_t; @@ -37,7 +39,7 @@ uint8_t bcal_cmac_init(const bcdesc_t* desc, const void* key, uint16_t keysize_b void bcal_cmac_free(bcal_cmac_ctx_t* ctx); void bcal_cmac_nextBlock(bcal_cmac_ctx_t* ctx, const void* block); void bcal_cmac_lastBlock(bcal_cmac_ctx_t* ctx, const void* block, uint16_t length_b); -void bcal_cmac_ctx2mac(void* dest, uint16_t length_b, const bcal_cmac_ctx_t* state); +void bcal_cmac_ctx2mac(void* dest, uint16_t length_b, const bcal_cmac_ctx_t* ctx); void bcal_cmac(void* dest, uint16_t out_length_b, const void* block, uint32_t length_b, bcal_cmac_ctx_t* ctx); #endif /* BCALCMAC_H_ */ diff --git a/bcal-eax.c b/bcal-eax.c new file mode 100644 index 0000000..78ddd51 --- /dev/null +++ b/bcal-eax.c @@ -0,0 +1,118 @@ +/* bca-eax.c */ +/* + This file is part of the AVR-Crypto-Lib. + Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + + +#include +#include "bcal-basic.h" +#include "blockcipher_descriptor.h" +#include "bcal-cmac.h" +#include "bcal-ctr.h" +#include "bcal-eax.h" + +uint8_t bcal_eax_init(const bcdesc_t* desc, const void* key, uint16_t keysize_b, bcal_eax_ctx_t* ctx){ + uint8_t r; + ctx->blocksize_B = (bcal_cipher_getBlocksize_b(desc)+7)/8; + ctx->nonce = malloc(ctx->blocksize_B); + if(ctx->nonce==NULL){ + return 0x81; + } + r = bcal_cmac_init(desc, key, keysize_b, &(ctx->ctag)); + if(r){ + return r; + } + r = bcal_cmac_init(desc, key, keysize_b, &(ctx->htag)); + if(r){ + return (r|0x10); + } + r = bcal_cmac_init(desc, key, keysize_b, &(ctx->ntag)); + if(r){ + return (r|0x20); + } + r = bcal_ctr_init(desc, key, keysize_b, NULL, &(ctx->cipher)); + if(r){ + return (r|0x30); + } + ctx->header_set=0; + uint8_t tmp[ctx->blocksize_B]; + memset(tmp, 0, ctx->blocksize_B); + bcal_cmac_nextBlock(&(ctx->ntag), tmp); + tmp[ctx->blocksize_B-1]=1; + bcal_cmac_nextBlock(&(ctx->htag), tmp); + tmp[ctx->blocksize_B-1]=2; + bcal_cmac_nextBlock(&(ctx->ctag), tmp); + return 0; +} + +void bcal_eax_free(bcal_eax_ctx_t* ctx){ + bcal_ctr_free(&(ctx->cipher)); + bcal_cmac_free(&(ctx->ctag)); + bcal_cmac_free(&(ctx->htag)); + bcal_cmac_free(&(ctx->ntag)); + free(ctx->nonce); +} + +void bcal_eax_loadNonce(const void* nonce, uint16_t length_b, bcal_eax_ctx_t* ctx){ + bcal_cmac_lastBlock(&(ctx->ntag), nonce, length_b); + bcal_cmac_ctx2mac(ctx->nonce, ctx->blocksize_B*8, &(ctx->ntag)); + bcal_ctr_loadIV(ctx->nonce, &(ctx->cipher)); +} + +void bcal_eax_addNextHeader(const void* header, bcal_eax_ctx_t* ctx){ + bcal_cmac_nextBlock(&(ctx->htag), header); +} + +void bcal_eax_addLastHeader(const void* header, uint16_t length_b, bcal_eax_ctx_t* ctx){ + bcal_cmac_lastBlock(&(ctx->htag), header, length_b); + ctx->header_set = 1; +} + +void bcal_eax_encNextBlock(void* block, bcal_eax_ctx_t* ctx){ + bcal_ctr_encNext(block, &(ctx->cipher)); + bcal_cmac_nextBlock(&(ctx->ctag), block); +} + +void bcal_eax_encLastBlock(void* block, uint16_t length_b, bcal_eax_ctx_t* ctx){ + bcal_ctr_encMsg(NULL, block, length_b, &(ctx->cipher)); + bcal_cmac_lastBlock(&(ctx->ctag), block, length_b); +} + +void bcal_eax_decNextBlock(void* block, bcal_eax_ctx_t* ctx){ + bcal_cmac_nextBlock(&(ctx->ctag), block); + bcal_ctr_decNext(block, &(ctx->cipher)); +} + +void bcal_eax_decLastBlock(void* block, uint16_t length_b, bcal_eax_ctx_t* ctx){ + bcal_cmac_lastBlock(&(ctx->ctag), block, length_b); + bcal_ctr_decMsg(NULL, block, length_b, &(ctx->cipher)); +} + +void bcal_eax_ctx2tag(void* dest, uint16_t length_b, bcal_eax_ctx_t* ctx){ + uint8_t tmp[ctx->blocksize_B]; + if(ctx->header_set==0){ + bcal_cmac_lastBlock(&(ctx->htag), NULL, 0); + } + + bcal_cmac_ctx2mac(tmp, ctx->blocksize_B*8, &(ctx->htag)); + memxor(ctx->nonce, tmp, ctx->blocksize_B); + + bcal_cmac_ctx2mac(tmp, ctx->blocksize_B*8, &(ctx->ctag)); + memxor(ctx->nonce, tmp, ctx->blocksize_B); + memcpy(dest, ctx->nonce, (length_b+7)/8); +} + diff --git a/bcal-eax.h b/bcal-eax.h new file mode 100644 index 0000000..190eee9 --- /dev/null +++ b/bcal-eax.h @@ -0,0 +1,53 @@ +/* bcal-eax.h */ +/* + This file is part of the AVR-Crypto-Lib. + Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef BCALEAX_H_ +#define BCALEAX_H_ + +#include +#include +#include "bcal-basic.h" +#include "blockcipher_descriptor.h" +#include "bcal-cmac.h" +#include "bcal-ctr.h" + +typedef struct{ + uint8_t* nonce; + bcal_cmac_ctx_t ntag; + bcal_cmac_ctx_t ctag; + bcal_cmac_ctx_t htag; + bcal_ctr_ctx_t cipher; + uint8_t blocksize_B; + uint8_t header_set; +} bcal_eax_ctx_t; + +uint8_t bcal_eax_init(const bcdesc_t* desc, const void* key, uint16_t keysize_b, bcal_eax_ctx_t* ctx); +void bcal_eax_free(bcal_eax_ctx_t* ctx); +void bcal_eax_loadNonce(const void* nonce, uint16_t length_b, bcal_eax_ctx_t* ctx); +void bcal_eax_addNextHeader(const void* header, bcal_eax_ctx_t* ctx); +void bcal_eax_addLastHeader(const void* header, uint16_t length_b, bcal_eax_ctx_t* ctx); +void bcal_eax_encNextBlock(void* block, bcal_eax_ctx_t* ctx); +void bcal_eax_encLastBlock(void* block, uint16_t length_b, bcal_eax_ctx_t* ctx); +void bcal_eax_decNextBlock(void* block, bcal_eax_ctx_t* ctx); +void bcal_eax_decLastBlock(void* block, uint16_t length_b, bcal_eax_ctx_t* ctx); +void bcal_eax_ctx2tag(void* dest, uint16_t length_b, bcal_eax_ctx_t* ctx); +//void bcal_eax(void* dest, uint16_t out_length_b, const void* block, uint32_t length_b, bcal_eax_ctx_t* ctx); + +#endif /* BCALEAX_H_ */ + diff --git a/mkfiles/aes.mk b/mkfiles/aes.mk index e8459b6..ebe67b6 100644 --- a/mkfiles/aes.mk +++ b/mkfiles/aes.mk @@ -10,8 +10,9 @@ $(ALGO_NAME)_OBJ := aes_enc-asm.o aes_dec-asm.o aes_sbox-asm.o aes_invsbox- $(ALGO_NAME)_TEST_BIN := main-aes-test.o $(CLI_STD) \ nessie_bc_test.o nessie_common.o performance_test.o memxor.o \ bcal_aes128.o bcal_aes192.o bcal_aes256.o bcal-basic.o bcal-cbc.o \ - keysize_descriptor.o dump-asm.o dump-decl.o bcal-cfb_byte.o \ - bcal-cfb_bit.o bcal-ofb.o bcal-ctr.o bcal-cmac.o cmacvs.o + keysize_descriptor.o dump-asm.o dump-decl.o bcal-cfb_byte.o \ + bcal-cfb_bit.o bcal-ofb.o bcal-ctr.o bcal-cmac.o cmacvs.o \ + bcal-eax.o $(ALGO_NAME)_NESSIE_TEST := test nessie $(ALGO_NAME)_PERFORMANCE_TEST := performance diff --git a/mkfiles/aes_c.mk b/mkfiles/aes_c.mk index 568ebec..fa99606 100644 --- a/mkfiles/aes_c.mk +++ b/mkfiles/aes_c.mk @@ -11,10 +11,11 @@ $(ALGO_NAME)_OBJ := aes_enc.o aes_dec.o aes_sbox.o aes_invsbox.o \ aes128_enc.o aes128_dec.o aes192_enc.o aes192_dec.o \ aes256_enc.o aes256_dec.o $(ALGO_NAME)_TEST_BIN := main-aes-test.o $(CLI_STD) \ - nessie_bc_test.o nessie_common.o performance_test.o memxor.o \ + nessie_bc_test.o nessie_common.o performance_test.o memxor.o \ bcal_aes128.o bcal_aes192.o bcal_aes256.o bcal-basic.o bcal-cbc.o \ - keysize_descriptor.o dump-asm.o dump-decl.o bcal-cfb_byte.o \ - bcal-cfb_bit.o bcal-ofb.o bcal-ctr.o bcal-cmac.o + keysize_descriptor.o dump-asm.o dump-decl.o bcal-cfb_byte.o \ + bcal-cfb_bit.o bcal-ofb.o bcal-ctr.o bcal-cmac.o cmacvs.o \ + bcal-eax.o $(ALGO_NAME)_NESSIE_TEST := test nessie $(ALGO_NAME)_PERFORMANCE_TEST := performance diff --git a/test_src/main-aes-test.c b/test_src/main-aes-test.c index c4b9adc..f075250 100644 --- a/test_src/main-aes-test.c +++ b/test_src/main-aes-test.c @@ -42,6 +42,7 @@ #include "bcal-ofb.h" #include "bcal-ctr.h" #include "bcal-cmac.h" +#include "bcal-eax.h" #include "cmacvs.h" #include @@ -526,6 +527,158 @@ void testrun_aes192_cmac0(void){ cli_hexdump_block(tag, 2, 4, 16); bcal_cmac_free(&ctx); } +/* +MSG: +KEY: 233952DEE4D5ED5F9B9C6D6FF80FF478 +NONCE: 62EC67F9C3A4A407FCB2A8C49031A8B3 +HEADER: 6BFB914FD07EAE6B +CIPHER: E037830E8389F27B025A2D6527E79D01 +*/ + +void testrun_aes128_eax(void){ + uint8_t key[16]= { + 0x23, 0x39, 0x52, 0xDE, 0xE4, 0xD5, 0xED, 0x5F, + 0x9B, 0x9C, 0x6D, 0x6F, 0xF8, 0x0F, 0xF4, 0x78 + }; + uint8_t nonce[16] = { + 0x62, 0xEC, 0x67, 0xF9, 0xC3, 0xA4, 0xA4, 0x07, + 0xFC, 0xB2, 0xA8, 0xC4, 0x90, 0x31, 0xA8, 0xB3 + }; + uint8_t header[8] = { + 0x6B, 0xFB, 0x91, 0x4F, 0xD0, 0x7E, 0xAE, 0x6B + }; + uint8_t tag[16]; + + bcal_eax_ctx_t ctx; + uint8_t r; + + + cli_putstr_P(PSTR("\r\n** AES128-EAX-TEST **")); + + cli_putstr_P(PSTR("\r\n key: ")); + cli_hexdump(key, 16); + cli_putstr_P(PSTR("\r\n nonce: ")); + cli_hexdump(nonce, 16); + cli_putstr_P(PSTR("\r\n header: ")); + cli_hexdump(header, 8); + r = bcal_eax_init(&aes128_desc, key, 128, &ctx); + cli_putstr_P(PSTR("\r\n init = 0x")); + cli_hexdump(&r, 1); + if(r) + return; + bcal_eax_loadNonce(nonce, 16*8, &ctx); + bcal_eax_addLastHeader(header, 8*8, &ctx); + bcal_eax_encLastBlock(NULL, 0, &ctx); + bcal_eax_ctx2tag(tag, 128, &ctx); + cli_putstr_P(PSTR("\r\n tag: ")); + cli_hexdump_block(tag, 16, 4, 16); + bcal_eax_free(&ctx); +} + +/* +MSG: F7FB +KEY: 91945D3F4DCBEE0BF45EF52255F095A4 +NONCE: BECAF043B0A23D843194BA972C66DEBD +HEADER: FA3BFD4806EB53FA +CIPHER: + */ +void testrun_aes128_eax2(void){ + uint8_t key[16]= { + 0x91, 0x94, 0x5D, 0x3F, 0x4D, 0xCB, 0xEE, 0x0B, + 0xF4, 0x5E, 0xF5, 0x22, 0x55, 0xF0, 0x95, 0xA4, + }; + uint8_t msg[2] = { 0xF7, 0xFB }; + uint8_t nonce[16] = { + 0xBE, 0xCA, 0xF0, 0x43, 0xB0, 0xA2, 0x3D, 0x84, + 0x31, 0x94, 0xBA, 0x97, 0x2C, 0x66, 0xDE, 0xBD, + }; + uint8_t header[8] = { + 0xFA, 0x3B, 0xFD, 0x48, 0x06, 0xEB, 0x53, 0xFA + }; + uint8_t tag[16]; + + bcal_eax_ctx_t ctx; + uint8_t r; + + + cli_putstr_P(PSTR("\r\n** AES128-EAX2-TEST **")); + + cli_putstr_P(PSTR("\r\n key: ")); + cli_hexdump(key, 16); + cli_putstr_P(PSTR("\r\n msg: ")); + cli_hexdump(msg, 2); + cli_putstr_P(PSTR("\r\n nonce: ")); + cli_hexdump(nonce, 16); + cli_putstr_P(PSTR("\r\n header: ")); + cli_hexdump(header, 8); + r = bcal_eax_init(&aes128_desc, key, 128, &ctx); + cli_putstr_P(PSTR("\r\n init = 0x")); + cli_hexdump(&r, 1); + if(r) + return; + bcal_eax_loadNonce(nonce, 16*8, &ctx); + bcal_eax_addLastHeader(header, 8*8, &ctx); + bcal_eax_encLastBlock(msg, 2*8, &ctx); + bcal_eax_ctx2tag(tag, 128, &ctx); + cli_putstr_P(PSTR("\r\n cipher: ")); + cli_hexdump_block(msg, 2, 4, 16); + cli_putstr_P(PSTR("\r\n tag: ")); + cli_hexdump_block(tag, 16, 4, 16); + bcal_eax_free(&ctx); +} +/* +MSG: 1A47CB4933 +KEY: 01F74AD64077F2E704C0F60ADA3DD523 +NONCE: 70C3DB4F0D26368400A10ED05D2BFF5E +HEADER: 234A3463C1264AC6 +CIPHER: +*/ +void testrun_aes128_eax3(void){ + uint8_t key[16]= { + 0x01, 0xF7, 0x4A, 0xD6, 0x40, 0x77, 0xF2, 0xE7, + 0x04, 0xC0, 0xF6, 0x0A, 0xDA, 0x3D, 0xD5, 0x23 + }; + uint8_t msg[5] = { + 0x1A, 0x47, 0xCB, 0x49, 0x33 + }; + uint8_t nonce[16] = { + 0x70, 0xC3, 0xDB, 0x4F, 0x0D, 0x26, 0x36, 0x84, + 0x00, 0xA1, 0x0E, 0xD0, 0x5D, 0x2B, 0xFF, 0x5E + }; + uint8_t header[8] = { + 0x23, 0x4A, 0x34, 0x63, 0xC1, 0x26, 0x4A, 0xC6 + }; + uint8_t tag[16]; + + bcal_eax_ctx_t ctx; + uint8_t r; + + + cli_putstr_P(PSTR("\r\n** AES128-EAX3-TEST **")); + + cli_putstr_P(PSTR("\r\n key: ")); + cli_hexdump(key, 16); + cli_putstr_P(PSTR("\r\n msg: ")); + cli_hexdump(msg, 5); + cli_putstr_P(PSTR("\r\n nonce: ")); + cli_hexdump(nonce, 16); + cli_putstr_P(PSTR("\r\n header: ")); + cli_hexdump(header, 8); + r = bcal_eax_init(&aes128_desc, key, 128, &ctx); + cli_putstr_P(PSTR("\r\n init = 0x")); + cli_hexdump(&r, 1); + if(r) + return; + bcal_eax_loadNonce(nonce, 16*8, &ctx); + bcal_eax_addLastHeader(header, 8*8, &ctx); + bcal_eax_encLastBlock(msg, 5*8, &ctx); + bcal_eax_ctx2tag(tag, 128, &ctx); + cli_putstr_P(PSTR("\r\n cipher: ")); + cli_hexdump_block(msg, 5, 4, 16); + cli_putstr_P(PSTR("\r\n tag: ")); + cli_hexdump_block(tag, 16, 4, 16); + bcal_eax_free(&ctx); +} /*****************************************************************************/ @@ -669,6 +822,9 @@ const char testctr_str[] PROGMEM = "testctr"; const char testcmac_str[] PROGMEM = "testcmac"; const char testcmac72_str[] PROGMEM = "testcmac72"; const char testcmac0_str[] PROGMEM = "testcmac0"; +const char testeax_str[] PROGMEM = "testeax"; +const char testeax2_str[] PROGMEM = "testeax2"; +const char testeax3_str[] PROGMEM = "testeax3"; const char cmacvs_list_str[] PROGMEM = "cmacvs_list"; const char cmacvs_set_str[] PROGMEM = "cmacvs_set"; const char cmacvs_test1_str[] PROGMEM = "cmacvs_test1"; @@ -689,6 +845,9 @@ cmdlist_entry_t cmdlist[] PROGMEM = { { testcmac_str, NULL, testrun_aes128_cmac }, { testcmac72_str, NULL, testrun_aes128_cmac72 }, { testcmac0_str, NULL, testrun_aes192_cmac0 }, + { testeax_str, NULL, testrun_aes128_eax }, + { testeax2_str, NULL, testrun_aes128_eax2 }, + { testeax3_str, NULL, testrun_aes128_eax3 }, { cmacvs_list_str, NULL, cmacvs_listalgos }, { cmacvs_set_str, (void*)1, (void_fpt)cmacvs_setalgo }, { cmacvs_test1_str, NULL, cmacvs_test1 },