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:
parent
86f9b1c706
commit
30bff1d0f4
3 changed files with 74 additions and 10 deletions
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue