~ubuntu-branches/ubuntu/utopic/moonshot-gss-eap/utopic-backports

« back to all changes in this revision

Viewing changes to libeap/src/crypto/aes-eax.c

  • Committer: Package Import Robot
  • Author(s): Sam Hartman
  • Date: 2014-09-16 08:38:39 UTC
  • Revision ID: package-import@ubuntu.com-20140916083839-ipqco3thb1wcwvs0
Tags: upstream-0.9.2
ImportĀ upstreamĀ versionĀ 0.9.2

Show diffs side-by-side

added added

removed removed

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