1e5b75505Sopenharmony_ci/* 2e5b75505Sopenharmony_ci * AES-128 EAX 3e5b75505Sopenharmony_ci * 4e5b75505Sopenharmony_ci * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi> 5e5b75505Sopenharmony_ci * 6e5b75505Sopenharmony_ci * This software may be distributed under the terms of the BSD license. 7e5b75505Sopenharmony_ci * See README for more details. 8e5b75505Sopenharmony_ci */ 9e5b75505Sopenharmony_ci 10e5b75505Sopenharmony_ci#include "includes.h" 11e5b75505Sopenharmony_ci 12e5b75505Sopenharmony_ci#include "common.h" 13e5b75505Sopenharmony_ci#include "aes.h" 14e5b75505Sopenharmony_ci#include "aes_wrap.h" 15e5b75505Sopenharmony_ci 16e5b75505Sopenharmony_ci/** 17e5b75505Sopenharmony_ci * aes_128_eax_encrypt - AES-128 EAX mode encryption 18e5b75505Sopenharmony_ci * @key: Key for encryption (16 bytes) 19e5b75505Sopenharmony_ci * @nonce: Nonce for counter mode 20e5b75505Sopenharmony_ci * @nonce_len: Nonce length in bytes 21e5b75505Sopenharmony_ci * @hdr: Header data to be authenticity protected 22e5b75505Sopenharmony_ci * @hdr_len: Length of the header data bytes 23e5b75505Sopenharmony_ci * @data: Data to encrypt in-place 24e5b75505Sopenharmony_ci * @data_len: Length of data in bytes 25e5b75505Sopenharmony_ci * @tag: 16-byte tag value 26e5b75505Sopenharmony_ci * Returns: 0 on success, -1 on failure 27e5b75505Sopenharmony_ci */ 28e5b75505Sopenharmony_ciint aes_128_eax_encrypt(const u8 *key, const u8 *nonce, size_t nonce_len, 29e5b75505Sopenharmony_ci const u8 *hdr, size_t hdr_len, 30e5b75505Sopenharmony_ci u8 *data, size_t data_len, u8 *tag) 31e5b75505Sopenharmony_ci{ 32e5b75505Sopenharmony_ci u8 *buf; 33e5b75505Sopenharmony_ci size_t buf_len; 34e5b75505Sopenharmony_ci u8 nonce_mac[AES_BLOCK_SIZE], hdr_mac[AES_BLOCK_SIZE], 35e5b75505Sopenharmony_ci data_mac[AES_BLOCK_SIZE]; 36e5b75505Sopenharmony_ci int i, ret = -1; 37e5b75505Sopenharmony_ci 38e5b75505Sopenharmony_ci if (nonce_len > data_len) 39e5b75505Sopenharmony_ci buf_len = nonce_len; 40e5b75505Sopenharmony_ci else 41e5b75505Sopenharmony_ci buf_len = data_len; 42e5b75505Sopenharmony_ci if (hdr_len > buf_len) 43e5b75505Sopenharmony_ci buf_len = hdr_len; 44e5b75505Sopenharmony_ci buf_len += 16; 45e5b75505Sopenharmony_ci 46e5b75505Sopenharmony_ci buf = os_malloc(buf_len); 47e5b75505Sopenharmony_ci if (buf == NULL) 48e5b75505Sopenharmony_ci return -1; 49e5b75505Sopenharmony_ci 50e5b75505Sopenharmony_ci os_memset(buf, 0, 15); 51e5b75505Sopenharmony_ci 52e5b75505Sopenharmony_ci buf[15] = 0; 53e5b75505Sopenharmony_ci os_memcpy(buf + 16, nonce, nonce_len); 54e5b75505Sopenharmony_ci if (omac1_aes_128(key, buf, 16 + nonce_len, nonce_mac)) 55e5b75505Sopenharmony_ci goto fail; 56e5b75505Sopenharmony_ci 57e5b75505Sopenharmony_ci buf[15] = 1; 58e5b75505Sopenharmony_ci os_memcpy(buf + 16, hdr, hdr_len); 59e5b75505Sopenharmony_ci if (omac1_aes_128(key, buf, 16 + hdr_len, hdr_mac)) 60e5b75505Sopenharmony_ci goto fail; 61e5b75505Sopenharmony_ci 62e5b75505Sopenharmony_ci if (aes_128_ctr_encrypt(key, nonce_mac, data, data_len)) 63e5b75505Sopenharmony_ci goto fail; 64e5b75505Sopenharmony_ci buf[15] = 2; 65e5b75505Sopenharmony_ci os_memcpy(buf + 16, data, data_len); 66e5b75505Sopenharmony_ci if (omac1_aes_128(key, buf, 16 + data_len, data_mac)) 67e5b75505Sopenharmony_ci goto fail; 68e5b75505Sopenharmony_ci 69e5b75505Sopenharmony_ci for (i = 0; i < AES_BLOCK_SIZE; i++) 70e5b75505Sopenharmony_ci tag[i] = nonce_mac[i] ^ data_mac[i] ^ hdr_mac[i]; 71e5b75505Sopenharmony_ci 72e5b75505Sopenharmony_ci ret = 0; 73e5b75505Sopenharmony_cifail: 74e5b75505Sopenharmony_ci bin_clear_free(buf, buf_len); 75e5b75505Sopenharmony_ci 76e5b75505Sopenharmony_ci return ret; 77e5b75505Sopenharmony_ci} 78e5b75505Sopenharmony_ci 79e5b75505Sopenharmony_ci 80e5b75505Sopenharmony_ci/** 81e5b75505Sopenharmony_ci * aes_128_eax_decrypt - AES-128 EAX mode decryption 82e5b75505Sopenharmony_ci * @key: Key for decryption (16 bytes) 83e5b75505Sopenharmony_ci * @nonce: Nonce for counter mode 84e5b75505Sopenharmony_ci * @nonce_len: Nonce length in bytes 85e5b75505Sopenharmony_ci * @hdr: Header data to be authenticity protected 86e5b75505Sopenharmony_ci * @hdr_len: Length of the header data bytes 87e5b75505Sopenharmony_ci * @data: Data to encrypt in-place 88e5b75505Sopenharmony_ci * @data_len: Length of data in bytes 89e5b75505Sopenharmony_ci * @tag: 16-byte tag value 90e5b75505Sopenharmony_ci * Returns: 0 on success, -1 on failure, -2 if tag does not match 91e5b75505Sopenharmony_ci */ 92e5b75505Sopenharmony_ciint aes_128_eax_decrypt(const u8 *key, const u8 *nonce, size_t nonce_len, 93e5b75505Sopenharmony_ci const u8 *hdr, size_t hdr_len, 94e5b75505Sopenharmony_ci u8 *data, size_t data_len, const u8 *tag) 95e5b75505Sopenharmony_ci{ 96e5b75505Sopenharmony_ci u8 *buf; 97e5b75505Sopenharmony_ci size_t buf_len; 98e5b75505Sopenharmony_ci u8 nonce_mac[AES_BLOCK_SIZE], hdr_mac[AES_BLOCK_SIZE], 99e5b75505Sopenharmony_ci data_mac[AES_BLOCK_SIZE]; 100e5b75505Sopenharmony_ci int i; 101e5b75505Sopenharmony_ci 102e5b75505Sopenharmony_ci if (nonce_len > data_len) 103e5b75505Sopenharmony_ci buf_len = nonce_len; 104e5b75505Sopenharmony_ci else 105e5b75505Sopenharmony_ci buf_len = data_len; 106e5b75505Sopenharmony_ci if (hdr_len > buf_len) 107e5b75505Sopenharmony_ci buf_len = hdr_len; 108e5b75505Sopenharmony_ci buf_len += 16; 109e5b75505Sopenharmony_ci 110e5b75505Sopenharmony_ci buf = os_malloc(buf_len); 111e5b75505Sopenharmony_ci if (buf == NULL) 112e5b75505Sopenharmony_ci return -1; 113e5b75505Sopenharmony_ci 114e5b75505Sopenharmony_ci os_memset(buf, 0, 15); 115e5b75505Sopenharmony_ci 116e5b75505Sopenharmony_ci buf[15] = 0; 117e5b75505Sopenharmony_ci os_memcpy(buf + 16, nonce, nonce_len); 118e5b75505Sopenharmony_ci if (omac1_aes_128(key, buf, 16 + nonce_len, nonce_mac)) { 119e5b75505Sopenharmony_ci os_free(buf); 120e5b75505Sopenharmony_ci return -1; 121e5b75505Sopenharmony_ci } 122e5b75505Sopenharmony_ci 123e5b75505Sopenharmony_ci buf[15] = 1; 124e5b75505Sopenharmony_ci os_memcpy(buf + 16, hdr, hdr_len); 125e5b75505Sopenharmony_ci if (omac1_aes_128(key, buf, 16 + hdr_len, hdr_mac)) { 126e5b75505Sopenharmony_ci os_free(buf); 127e5b75505Sopenharmony_ci return -1; 128e5b75505Sopenharmony_ci } 129e5b75505Sopenharmony_ci 130e5b75505Sopenharmony_ci buf[15] = 2; 131e5b75505Sopenharmony_ci os_memcpy(buf + 16, data, data_len); 132e5b75505Sopenharmony_ci if (omac1_aes_128(key, buf, 16 + data_len, data_mac)) { 133e5b75505Sopenharmony_ci os_free(buf); 134e5b75505Sopenharmony_ci return -1; 135e5b75505Sopenharmony_ci } 136e5b75505Sopenharmony_ci 137e5b75505Sopenharmony_ci os_free(buf); 138e5b75505Sopenharmony_ci 139e5b75505Sopenharmony_ci for (i = 0; i < AES_BLOCK_SIZE; i++) { 140e5b75505Sopenharmony_ci if (tag[i] != (nonce_mac[i] ^ data_mac[i] ^ hdr_mac[i])) 141e5b75505Sopenharmony_ci return -2; 142e5b75505Sopenharmony_ci } 143e5b75505Sopenharmony_ci 144e5b75505Sopenharmony_ci return aes_128_ctr_encrypt(key, nonce_mac, data, data_len); 145e5b75505Sopenharmony_ci} 146