Commit 096782dd authored by Davide Galassi's avatar Davide Galassi

Merge branch 'feature/incremental_cmac' into 'master'

CMAC: incremental interface with fake incremental implementation

See merge request !9
parents 541ab0f1 17034e3b
Pipeline #46176171 passed with stages
in 1 minute and 37 seconds
...@@ -8,23 +8,30 @@ ...@@ -8,23 +8,30 @@
#ifndef CRY_CMAC_H_ #ifndef CRY_CMAC_H_
#define CRY_CMAC_H_ #define CRY_CMAC_H_
#include <cry/ciph.h>
#include <stddef.h> #include <stddef.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C"{ extern "C"{
#endif #endif
/** struct cry_cmac_ctx {
* Cipher based digest (CMAC). void *ciph_ctx; /**< Block cipher context */
* const struct cry_ciph_itf *ciph_itf; /**< Block cipher interface */
* @param mac Digest output (16 octets). unsigned char k1[16];
* @param input Input data. unsigned char k2[16];
* @param size Size of input data. unsigned char mac[16];
* @param key Key data. };
* @param keysize Size if key.
*/ typedef struct cry_cmac_ctx cry_cmac_ctx;
void cry_cmac_digest(unsigned char *mac, const unsigned char *input,
size_t size, const unsigned char *key, size_t keysize); void cry_cmac_init(cry_cmac_ctx *ctx, void *ciph_ctx,
const cry_ciph_itf *ciph_itf,
unsigned char *key, size_t keylen);
void cry_cmac_update(cry_cmac_ctx *ctx, const unsigned char *data, size_t len);
void cry_cmac_digest(cry_cmac_ctx *ctx, unsigned char *mac);
#ifdef __cplusplus #ifdef __cplusplus
} }
......
#include <cry/aes.h> #include <cry/cmac.h>
#include <string.h> #include <string.h>
static void xor_128(unsigned char *o, const unsigned char *a, static void xor_128(unsigned char *o, const unsigned char *a,
...@@ -10,15 +10,15 @@ static void xor_128(unsigned char *o, const unsigned char *a, ...@@ -10,15 +10,15 @@ static void xor_128(unsigned char *o, const unsigned char *a,
o[i] = a[i] ^ b[i]; o[i] = a[i] ^ b[i];
} }
static void cry_aes_cbc_compute_subkeys(struct cry_aes_ctx *aes, static void cbc_compute_subkeys(cry_cmac_ctx *ctx)
unsigned char *k1,
unsigned char *k2)
{ {
unsigned char blank[16] = {0}; unsigned char blank[16] = {0};
unsigned char msb; unsigned char msb;
size_t i; size_t i;
unsigned char *k1 = ctx->k1;
unsigned char *k2 = ctx->k2;
cry_aes_encrypt(aes, k1, blank, 16); ctx->ciph_itf->encrypt(ctx->ciph_ctx, k1, blank, 16);
msb = (k1[0] & 0x80); msb = (k1[0] & 0x80);
for (i = 0; i < 16; i++) { for (i = 0; i < 16; i++) {
...@@ -39,8 +39,7 @@ static void cry_aes_cbc_compute_subkeys(struct cry_aes_ctx *aes, ...@@ -39,8 +39,7 @@ static void cry_aes_cbc_compute_subkeys(struct cry_aes_ctx *aes,
k2[15] ^= 0x87; k2[15] ^= 0x87;
} }
static void padding(unsigned char *pad, const unsigned char *last, static void pad(unsigned char *pad, const unsigned char *last, size_t size)
size_t size)
{ {
size_t i; size_t i;
...@@ -54,25 +53,30 @@ static void padding(unsigned char *pad, const unsigned char *last, ...@@ -54,25 +53,30 @@ static void padding(unsigned char *pad, const unsigned char *last,
} }
} }
void cry_cmac_digest(unsigned char *mac, const unsigned char *input,
size_t size, const unsigned char *key, size_t keysize) void cry_cmac_init(cry_cmac_ctx *ctx, void *ciph_ctx,
const cry_ciph_itf *ciph_itf,
unsigned char *key, size_t keylen)
{
memset(ctx, 0, sizeof(*ctx));
ctx->ciph_ctx = ciph_ctx;
ctx->ciph_itf = ciph_itf;
ciph_itf->key_set(ciph_ctx, key, keylen);
cbc_compute_subkeys(ctx);
}
void cry_cmac_update(cry_cmac_ctx *ctx, const unsigned char *data, size_t len)
{ {
struct cry_aes_ctx aes;
unsigned char block[16], last[16], padded[16]; unsigned char block[16], last[16], padded[16];
unsigned char k1[16], k2[16];
size_t n, i; size_t n, i;
int flag; int flag;
cry_aes_key_set(&aes, key, keysize); n = (len + 15) / 16; /* n is number of rounds */
cry_aes_cbc_compute_subkeys(&aes, k1, k2);
n = (size + 15) / 16; /* n is number of rounds */
if (n == 0) { if (n == 0) {
n = 1; n = 1;
flag = 0; flag = 0;
} else { } else {
if ((size % 16) == 0) if ((len % 16) == 0)
flag = 1; /* last block is a complete block */ flag = 1; /* last block is a complete block */
else else
flag = 0; /* last block is not complete block */ flag = 0; /* last block is not complete block */
...@@ -80,18 +84,23 @@ void cry_cmac_digest(unsigned char *mac, const unsigned char *input, ...@@ -80,18 +84,23 @@ void cry_cmac_digest(unsigned char *mac, const unsigned char *input,
if (flag) { if (flag) {
/* last block is complete block */ /* last block is complete block */
xor_128(last, &input[16*(n-1)], k1); xor_128(last, &data[16*(n-1)], ctx->k1);
} else { } else {
padding(padded, &input[16*(n-1)], size % 16); pad(padded, &data[16*(n-1)], len % 16);
xor_128(last, padded, k2); xor_128(last, padded, ctx->k2);
} }
memset(mac, 0, 16); memset(ctx->mac, 0, 16);
for (i = 0; i < (n - 1); i++) { for (i = 0; i < (n - 1); i++) {
xor_128(block, mac, &input[16*i]); xor_128(block, ctx->mac, &data[16*i]);
cry_aes_encrypt(&aes, mac, block, 16); ctx->ciph_itf->encrypt(&ctx->ciph_ctx, ctx->mac, block, 16);
} }
xor_128(block, mac, last); xor_128(block, ctx->mac, last);
cry_aes_encrypt(&aes, mac, block, 16); ctx->ciph_itf->encrypt(&ctx->ciph_ctx, ctx->mac, block, 16);
}
void cry_cmac_digest(cry_cmac_ctx *ctx, unsigned char *mac)
{
memcpy(mac, ctx->mac, sizeof(ctx->mac));
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment