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