aes-eax.c revision 214734
1195609Smp/* 259243Sobrien * AES-128 EAX 359243Sobrien * 459243Sobrien * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi> 559243Sobrien * 659243Sobrien * This program is free software; you can redistribute it and/or modify 759243Sobrien * it under the terms of the GNU General Public License version 2 as 859243Sobrien * published by the Free Software Foundation. 959243Sobrien * 1059243Sobrien * Alternatively, this software may be distributed under the terms of BSD 1159243Sobrien * license. 1259243Sobrien * 1359243Sobrien * See README and COPYING for more details. 1459243Sobrien */ 1559243Sobrien 1659243Sobrien#include "includes.h" 17100616Smp 1859243Sobrien#include "common.h" 1959243Sobrien#include "aes.h" 2059243Sobrien#include "aes_wrap.h" 2159243Sobrien 2259243Sobrien/** 2359243Sobrien * aes_128_eax_encrypt - AES-128 EAX mode encryption 2459243Sobrien * @key: Key for encryption (16 bytes) 2559243Sobrien * @nonce: Nonce for counter mode 2659243Sobrien * @nonce_len: Nonce length in bytes 2759243Sobrien * @hdr: Header data to be authenticity protected 2859243Sobrien * @hdr_len: Length of the header data bytes 2959243Sobrien * @data: Data to encrypt in-place 3059243Sobrien * @data_len: Length of data in bytes 3159243Sobrien * @tag: 16-byte tag value 3259243Sobrien * Returns: 0 on success, -1 on failure 3359243Sobrien */ 34100616Smpint aes_128_eax_encrypt(const u8 *key, const u8 *nonce, size_t nonce_len, 3559243Sobrien const u8 *hdr, size_t hdr_len, 36195609Smp u8 *data, size_t data_len, u8 *tag) 3759243Sobrien{ 38100616Smp u8 *buf; 3959243Sobrien size_t buf_len; 4059243Sobrien u8 nonce_mac[AES_BLOCK_SIZE], hdr_mac[AES_BLOCK_SIZE], 4159243Sobrien data_mac[AES_BLOCK_SIZE]; 4259243Sobrien int i, ret = -1; 4359243Sobrien 4459243Sobrien if (nonce_len > data_len) 4559243Sobrien buf_len = nonce_len; 4659243Sobrien else 4759243Sobrien buf_len = data_len; 4859243Sobrien if (hdr_len > buf_len) 4959243Sobrien buf_len = hdr_len; 5059243Sobrien buf_len += 16; 5159243Sobrien 5259243Sobrien buf = os_malloc(buf_len); 5359243Sobrien if (buf == NULL) 5459243Sobrien return -1; 5559243Sobrien 5659243Sobrien os_memset(buf, 0, 15); 5759243Sobrien 5859243Sobrien buf[15] = 0; 5959243Sobrien os_memcpy(buf + 16, nonce, nonce_len); 6059243Sobrien if (omac1_aes_128(key, buf, 16 + nonce_len, nonce_mac)) 6159243Sobrien goto fail; 62167465Smp 63167465Smp buf[15] = 1; 64167465Smp os_memcpy(buf + 16, hdr, hdr_len); 65167465Smp if (omac1_aes_128(key, buf, 16 + hdr_len, hdr_mac)) 66167465Smp goto fail; 67167465Smp 68167465Smp if (aes_128_ctr_encrypt(key, nonce_mac, data, data_len)) 69167465Smp goto fail; 70167465Smp buf[15] = 2; 71167465Smp os_memcpy(buf + 16, data, data_len); 72167465Smp if (omac1_aes_128(key, buf, 16 + data_len, data_mac)) 73167465Smp goto fail; 74167465Smp 75167465Smp for (i = 0; i < AES_BLOCK_SIZE; i++) 76167465Smp tag[i] = nonce_mac[i] ^ data_mac[i] ^ hdr_mac[i]; 77167465Smp 78167465Smp ret = 0; 7959243Sobrienfail: 8059243Sobrien os_free(buf); 8159243Sobrien 8259243Sobrien return ret; 8359243Sobrien} 8459243Sobrien 8559243Sobrien 86145479Smp/** 8759243Sobrien * aes_128_eax_decrypt - AES-128 EAX mode decryption 8859243Sobrien * @key: Key for decryption (16 bytes) 89167465Smp * @nonce: Nonce for counter mode 9059243Sobrien * @nonce_len: Nonce length in bytes 9159243Sobrien * @hdr: Header data to be authenticity protected 9259243Sobrien * @hdr_len: Length of the header data bytes 9359243Sobrien * @data: Data to encrypt in-place 9459243Sobrien * @data_len: Length of data in bytes 9559243Sobrien * @tag: 16-byte tag value 9659243Sobrien * Returns: 0 on success, -1 on failure, -2 if tag does not match 9759243Sobrien */ 9859243Sobrienint aes_128_eax_decrypt(const u8 *key, const u8 *nonce, size_t nonce_len, 9959243Sobrien const u8 *hdr, size_t hdr_len, 10059243Sobrien u8 *data, size_t data_len, const u8 *tag) 10159243Sobrien{ 10259243Sobrien u8 *buf; 10359243Sobrien size_t buf_len; 10459243Sobrien u8 nonce_mac[AES_BLOCK_SIZE], hdr_mac[AES_BLOCK_SIZE], 10559243Sobrien data_mac[AES_BLOCK_SIZE]; 10659243Sobrien int i; 10759243Sobrien 10859243Sobrien if (nonce_len > data_len) 10959243Sobrien buf_len = nonce_len; 11059243Sobrien else 11159243Sobrien buf_len = data_len; 11259243Sobrien if (hdr_len > buf_len) 11359243Sobrien buf_len = hdr_len; 11459243Sobrien buf_len += 16; 11559243Sobrien 11659243Sobrien buf = os_malloc(buf_len); 11759243Sobrien if (buf == NULL) 11859243Sobrien return -1; 11959243Sobrien 12059243Sobrien os_memset(buf, 0, 15); 12159243Sobrien 12259243Sobrien buf[15] = 0; 12359243Sobrien os_memcpy(buf + 16, nonce, nonce_len); 12459243Sobrien if (omac1_aes_128(key, buf, 16 + nonce_len, nonce_mac)) { 12559243Sobrien os_free(buf); 12659243Sobrien return -1; 12759243Sobrien } 12859243Sobrien 12959243Sobrien buf[15] = 1; 130167465Smp os_memcpy(buf + 16, hdr, hdr_len); 13159243Sobrien if (omac1_aes_128(key, buf, 16 + hdr_len, hdr_mac)) { 13259243Sobrien os_free(buf); 13359243Sobrien return -1; 13459243Sobrien } 13559243Sobrien 13659243Sobrien buf[15] = 2; 13759243Sobrien os_memcpy(buf + 16, data, data_len); 13859243Sobrien if (omac1_aes_128(key, buf, 16 + data_len, data_mac)) { 13959243Sobrien os_free(buf); 14059243Sobrien return -1; 14159243Sobrien } 14259243Sobrien 14359243Sobrien os_free(buf); 14459243Sobrien 14559243Sobrien for (i = 0; i < AES_BLOCK_SIZE; i++) { 14659243Sobrien if (tag[i] != (nonce_mac[i] ^ data_mac[i] ^ hdr_mac[i])) 14759243Sobrien return -2; 14859243Sobrien } 14959243Sobrien 15059243Sobrien return aes_128_ctr_encrypt(key, nonce_mac, data, data_len); 15159243Sobrien} 15259243Sobrien