Extend AES-CMAC routines to support 256-bit keys

omac1_aes_256() and omac1_aes_vector() can now be used to perform
256-bit CMAC operations similarly to the previously supported 128-bit
cases.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
Jouni Malinen 2015-01-23 16:59:33 +02:00 committed by Jouni Malinen
parent 86f9b1c706
commit 30bff1d0f4
3 changed files with 74 additions and 10 deletions

View file

@ -1,5 +1,5 @@
/* /*
* One-key CBC MAC (OMAC1) hash with AES-128 * One-key CBC MAC (OMAC1) hash with AES
* *
* Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi> * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
* *
@ -27,8 +27,9 @@ static void gf_mulx(u8 *pad)
/** /**
* omac1_aes_128_vector - One-Key CBC MAC (OMAC1) hash with AES-128 * omac1_aes_vector - One-Key CBC MAC (OMAC1) hash with AES
* @key: 128-bit key for the hash operation * @key: Key for the hash operation
* @key_len: Key length in octets
* @num_elem: Number of elements in the data vector * @num_elem: Number of elements in the data vector
* @addr: Pointers to the data areas * @addr: Pointers to the data areas
* @len: Lengths of the data blocks * @len: Lengths of the data blocks
@ -39,7 +40,7 @@ static void gf_mulx(u8 *pad)
* OMAC1 was standardized with the name CMAC by NIST in a Special Publication * OMAC1 was standardized with the name CMAC by NIST in a Special Publication
* (SP) 800-38B. * (SP) 800-38B.
*/ */
int omac1_aes_128_vector(const u8 *key, size_t num_elem, int omac1_aes_vector(const u8 *key, size_t key_len, size_t num_elem,
const u8 *addr[], const size_t *len, u8 *mac) const u8 *addr[], const size_t *len, u8 *mac)
{ {
void *ctx; void *ctx;
@ -47,7 +48,7 @@ int omac1_aes_128_vector(const u8 *key, size_t num_elem,
const u8 *pos, *end; const u8 *pos, *end;
size_t i, e, left, total_len; size_t i, e, left, total_len;
ctx = aes_encrypt_init(key, 16); ctx = aes_encrypt_init(key, key_len);
if (ctx == NULL) if (ctx == NULL)
return -1; return -1;
os_memset(cbc, 0, AES_BLOCK_SIZE); os_memset(cbc, 0, AES_BLOCK_SIZE);
@ -113,6 +114,26 @@ int omac1_aes_128_vector(const u8 *key, size_t num_elem,
} }
/**
* omac1_aes_128_vector - One-Key CBC MAC (OMAC1) hash with AES-128
* @key: 128-bit key for the hash operation
* @num_elem: Number of elements in the data vector
* @addr: Pointers to the data areas
* @len: Lengths of the data blocks
* @mac: Buffer for MAC (128 bits, i.e., 16 bytes)
* Returns: 0 on success, -1 on failure
*
* This is a mode for using block cipher (AES in this case) for authentication.
* OMAC1 was standardized with the name CMAC by NIST in a Special Publication
* (SP) 800-38B.
*/
int omac1_aes_128_vector(const u8 *key, size_t num_elem,
const u8 *addr[], const size_t *len, u8 *mac)
{
return omac1_aes_vector(key, 16, num_elem, addr, len, mac);
}
/** /**
* omac1_aes_128 - One-Key CBC MAC (OMAC1) hash with AES-128 (aka AES-CMAC) * omac1_aes_128 - One-Key CBC MAC (OMAC1) hash with AES-128 (aka AES-CMAC)
* @key: 128-bit key for the hash operation * @key: 128-bit key for the hash operation
@ -129,3 +150,21 @@ int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
{ {
return omac1_aes_128_vector(key, 1, &data, &data_len, mac); return omac1_aes_128_vector(key, 1, &data, &data_len, mac);
} }
/**
* omac1_aes_256 - One-Key CBC MAC (OMAC1) hash with AES-256 (aka AES-CMAC)
* @key: 256-bit key for the hash operation
* @data: Data buffer for which a MAC is determined
* @data_len: Length of data buffer in bytes
* @mac: Buffer for MAC (128 bits, i.e., 16 bytes)
* Returns: 0 on success, -1 on failure
*
* This is a mode for using block cipher (AES in this case) for authentication.
* OMAC1 was standardized with the name CMAC by NIST in a Special Publication
* (SP) 800-38B.
*/
int omac1_aes_256(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
{
return omac1_aes_vector(key, 32, 1, &data, &data_len, mac);
}

View file

@ -2,7 +2,7 @@
* AES-based functions * AES-based functions
* *
* - AES Key Wrap Algorithm (RFC3394) * - AES Key Wrap Algorithm (RFC3394)
* - One-Key CBC MAC (OMAC1) hash with AES-128 * - One-Key CBC MAC (OMAC1) hash with AES-128 and AES-256
* - AES-128 CTR mode encryption * - AES-128 CTR mode encryption
* - AES-128 EAX mode encryption/decryption * - AES-128 EAX mode encryption/decryption
* - AES-128 CBC * - AES-128 CBC
@ -22,11 +22,16 @@ int __must_check aes_wrap(const u8 *kek, size_t kek_len, int n, const u8 *plain,
u8 *cipher); u8 *cipher);
int __must_check aes_unwrap(const u8 *kek, size_t kek_len, int n, int __must_check aes_unwrap(const u8 *kek, size_t kek_len, int n,
const u8 *cipher, u8 *plain); const u8 *cipher, u8 *plain);
int __must_check omac1_aes_vector(const u8 *key, size_t key_len,
size_t num_elem, const u8 *addr[],
const size_t *len, u8 *mac);
int __must_check omac1_aes_128_vector(const u8 *key, size_t num_elem, int __must_check omac1_aes_128_vector(const u8 *key, size_t num_elem,
const u8 *addr[], const size_t *len, const u8 *addr[], const size_t *len,
u8 *mac); u8 *mac);
int __must_check omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, int __must_check omac1_aes_128(const u8 *key, const u8 *data, size_t data_len,
u8 *mac); u8 *mac);
int __must_check omac1_aes_256(const u8 *key, const u8 *data, size_t data_len,
u8 *mac);
int __must_check aes_128_encrypt_block(const u8 *key, const u8 *in, u8 *out); int __must_check aes_128_encrypt_block(const u8 *key, const u8 *in, u8 *out);
int __must_check aes_128_ctr_encrypt(const u8 *key, const u8 *nonce, int __must_check aes_128_ctr_encrypt(const u8 *key, const u8 *nonce,
u8 *data, size_t data_len); u8 *data, size_t data_len);

View file

@ -795,7 +795,7 @@ int crypto_get_random(void *buf, size_t len)
#ifdef CONFIG_OPENSSL_CMAC #ifdef CONFIG_OPENSSL_CMAC
int omac1_aes_128_vector(const u8 *key, size_t num_elem, int omac1_aes_vector(const u8 *key, size_t key_len, size_t num_elem,
const u8 *addr[], const size_t *len, u8 *mac) const u8 *addr[], const size_t *len, u8 *mac)
{ {
CMAC_CTX *ctx; CMAC_CTX *ctx;
@ -806,8 +806,15 @@ int omac1_aes_128_vector(const u8 *key, size_t num_elem,
if (ctx == NULL) if (ctx == NULL)
return -1; return -1;
if (key_len == 32) {
if (!CMAC_Init(ctx, key, 32, EVP_aes_256_cbc(), NULL))
goto fail;
} else if (key_len == 16) {
if (!CMAC_Init(ctx, key, 16, EVP_aes_128_cbc(), NULL)) if (!CMAC_Init(ctx, key, 16, EVP_aes_128_cbc(), NULL))
goto fail; goto fail;
} else {
goto fail;
}
for (i = 0; i < num_elem; i++) { for (i = 0; i < num_elem; i++) {
if (!CMAC_Update(ctx, addr[i], len[i])) if (!CMAC_Update(ctx, addr[i], len[i]))
goto fail; goto fail;
@ -822,10 +829,23 @@ fail:
} }
int omac1_aes_128_vector(const u8 *key, size_t num_elem,
const u8 *addr[], const size_t *len, u8 *mac)
{
return omac1_aes_vector(key, 16, num_elem, addr, len, mac);
}
int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac) int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
{ {
return omac1_aes_128_vector(key, 1, &data, &data_len, mac); return omac1_aes_128_vector(key, 1, &data, &data_len, mac);
} }
int omac1_aes_256(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
{
return omac1_aes_vector(key, 32, 1, &data, &data_len, mac);
}
#endif /* CONFIG_OPENSSL_CMAC */ #endif /* CONFIG_OPENSSL_CMAC */