1
0
Fork 0
nrf51-cryptolib/ckdf.c

54 lines
1.3 KiB
C

/* CMAC Key Derivation Function
HKDF, but with CMAC
Based on ietf draft-agl-ckdf-00
Shawn Nock - <nock@nocko.se>
*/
#include <stdint.h>
#include <stdio.h>
#include "cmac.h"
void ckdf_extract(uint8_t *prk, const uint8_t *salt, const uint8_t *ikm,
uint32_t ikm_len) {
uint8_t zeros[16] = {0};
if (salt == NULL) {
cmac_aes128_init(zeros);
} else {
cmac_aes128_init(salt);
}
cmac_aes128(prk, (uint8_t *)ikm, ikm_len, 16);
}
void ckdf_expand(uint8_t *okm, uint8_t *prk, uint8_t *info, uint32_t info_len,
uint32_t okm_len) {
uint32_t num_blocks = okm_len / 16;
/* Simulate ceiling division instead of C std floor */
uint8_t remainder = okm_len % 16;
if (remainder) {
num_blocks++;
}
cmac_aes128_init(prk);
uint8_t t[16 + info_len + 1];
uint8_t *initial = &t[16];
memset(t, 0, 16);
for (uint32_t i = 0; i < num_blocks; i++) {
*(initial + info_len) = i + 1;
if (i == 0) {
memcpy(initial, info, info_len);
cmac_aes128(t, initial, info_len + 1, 16);
} else {
cmac_aes128(t, t, sizeof(t), 16);
}
if (i == num_blocks - 1 && remainder) {
memcpy(okm + 16 * i, t, remainder);
} else {
memcpy(okm + 16 * i, t, 16);
}
}
return;
}