2 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
7 * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
8 * Sun elects to license this software under the BSD license.
9 * See README for more details.
16 #include <sys/types.h>
18 #include <openssl/aes.h>
19 #include <openssl/hmac.h>
20 #include <openssl/rc4.h>
25 * @kek: key encryption key (KEK)
26 * @n: length of the wrapped key in 64-bit units; e.g., 2 = 128-bit = 16 bytes
27 * @plain: plaintext key to be wrapped, n * 64 bit
28 * @cipher: wrapped key, (n + 1) * 64 bit
31 aes_wrap(uint8_t *kek
, int n
, uint8_t *plain
, uint8_t *cipher
)
33 uint8_t *a
, *r
, b
[16];
40 /* 1) Initialize variables. */
41 (void) memset(a
, 0xa6, 8);
42 (void) memcpy(r
, plain
, 8 * n
);
44 (void) AES_set_encrypt_key(kek
, 128, &key
);
47 * 2) Calculate intermediate values.
50 * B = AES(K, A | R[i])
51 * A = MSB(64, B) ^ t where t = (n*j)+i
54 for (j
= 0; j
<= 5; j
++) {
56 for (i
= 1; i
<= n
; i
++) {
57 (void) memcpy(b
, a
, 8);
58 (void) memcpy(b
+ 8, r
, 8);
59 AES_encrypt(b
, b
, &key
);
60 (void) memcpy(a
, b
, 8);
62 (void) memcpy(r
, b
+ 8, 8);
68 * 3) Output the results.
70 * These are already in @cipher due to the location of temporary
76 * @kek: key encryption key (KEK)
77 * @n: length of the wrapped key in 64-bit units; e.g., 2 = 128-bit = 16 bytes
78 * @cipher: wrapped key to be unwrapped, (n + 1) * 64 bit
79 * @plain: plaintext key, n * 64 bit
82 aes_unwrap(uint8_t *kek
, int n
, uint8_t *cipher
, uint8_t *plain
)
84 uint8_t a
[8], *r
, b
[16];
88 /* 1) Initialize variables. */
89 (void) memcpy(a
, cipher
, 8);
91 (void) memcpy(r
, cipher
+ 8, 8 * n
);
93 (void) AES_set_decrypt_key(kek
, 128, &key
);
96 * 2) Compute intermediate values.
99 * B = AES-1(K, (A ^ t) | R[i]) where t = n*j+i
103 for (j
= 5; j
>= 0; j
--) {
104 r
= plain
+ (n
- 1) * 8;
105 for (i
= n
; i
>= 1; i
--) {
106 (void) memcpy(b
, a
, 8);
109 (void) memcpy(b
+ 8, r
, 8);
110 AES_decrypt(b
, b
, &key
);
111 (void) memcpy(a
, b
, 8);
112 (void) memcpy(r
, b
+ 8, 8);
120 * These are already in @plain due to the location of temporary
121 * variables. Just verify that the IV matches with the expected value.
123 for (i
= 0; i
< 8; i
++) {
134 hmac_sha1(unsigned char *key
, unsigned int key_len
,
135 unsigned char *data
, unsigned int data_len
, unsigned char *mac
)
137 unsigned int mac_len
= 0;
138 (void) HMAC(EVP_sha1(), key
, key_len
, data
, data_len
, mac
, &mac_len
);
143 hmac_sha1_vector(unsigned char *key
, unsigned int key_len
, size_t num_elem
,
144 unsigned char *addr
[], unsigned int *len
, unsigned char *mac
)
146 unsigned char *buf
, *ptr
;
150 for (i
= 0; i
< num_elem
; i
++)
153 buf
= malloc(buf_len
);
156 for (i
= 0; i
< num_elem
; i
++) {
157 (void) memcpy(ptr
, addr
[i
], len
[i
]);
161 hmac_sha1(key
, key_len
, buf
, buf_len
, mac
);
168 sha1_prf(unsigned char *key
, unsigned int key_len
,
169 char *label
, unsigned char *data
, unsigned int data_len
,
170 unsigned char *buf
, size_t buf_len
)
172 uint8_t zero
= 0, counter
= 0;
174 uint8_t hash
[SHA1_MAC_LEN
];
175 size_t label_len
= strlen(label
);
177 unsigned char *addr
[4];
180 addr
[0] = (uint8_t *)label
;
190 while (pos
< buf_len
) {
191 plen
= buf_len
- pos
;
192 if (plen
>= SHA1_MAC_LEN
) {
193 hmac_sha1_vector(key
, key_len
, 4, addr
, len
, &buf
[pos
]);
196 hmac_sha1_vector(key
, key_len
, 4, addr
, len
, hash
);
197 (void) memcpy(&buf
[pos
], hash
, plen
);
205 pbkdf2_sha1(char *passphrase
, char *ssid
, size_t ssid_len
, int iterations
,
206 unsigned char *buf
, size_t buflen
)
208 (void) PKCS5_PBKDF2_HMAC_SHA1(passphrase
, -1, (unsigned char *)ssid
,
209 ssid_len
, iterations
, buflen
, buf
);
213 rc4_skip(uint8_t *key
, size_t keylen
, size_t skip
,
214 uint8_t *data
, size_t data_len
)
219 buf_len
= skip
+ data_len
;
220 buf
= malloc(buf_len
);
223 bcopy(data
, buf
+ skip
, data_len
);
225 rc4(buf
, buf_len
, key
, keylen
);
227 bcopy(buf
+ skip
, data
, data_len
);
232 rc4(uint8_t *buf
, size_t len
, uint8_t *key
, size_t key_len
)
236 RC4_set_key(&k
, key_len
, key
);
237 RC4(&k
, len
, buf
, buf
);
241 hmac_md5_vector(uint8_t *key
, size_t key_len
, size_t num_elem
,
242 uint8_t *addr
[], size_t *len
, uint8_t *mac
)
244 unsigned char *buf
, *ptr
;
248 for (i
= 0; i
< num_elem
; i
++)
251 buf
= malloc(buf_len
);
254 for (i
= 0; i
< num_elem
; i
++) {
255 (void) memcpy(ptr
, addr
[i
], len
[i
]);
259 hmac_md5(key
, key_len
, buf
, buf_len
, mac
);
265 hmac_md5(uint8_t *key
, size_t key_len
, uint8_t *data
,
266 size_t data_len
, uint8_t *mac
)
268 unsigned int mac_len
= 0;
269 (void) HMAC(EVP_md5(), key
, key_len
, data
, data_len
, mac
, &mac_len
);