4d90dd0ecdace5438d0a722068b380d85fd8cea5Quaker Fang * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
a399b7655a1d835aa8606c2b29e4e777baac8635zf * Use is subject to license terms.
a399b7655a1d835aa8606c2b29e4e777baac8635zf * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
a399b7655a1d835aa8606c2b29e4e777baac8635zf * Sun elects to license this software under the BSD license.
a399b7655a1d835aa8606c2b29e4e777baac8635zf * See README for more details.
a399b7655a1d835aa8606c2b29e4e777baac8635zf * @kek: key encryption key (KEK)
a399b7655a1d835aa8606c2b29e4e777baac8635zf * @n: length of the wrapped key in 64-bit units; e.g., 2 = 128-bit = 16 bytes
a399b7655a1d835aa8606c2b29e4e777baac8635zf * @plain: plaintext key to be wrapped, n * 64 bit
a399b7655a1d835aa8606c2b29e4e777baac8635zf * @cipher: wrapped key, (n + 1) * 64 bit
a399b7655a1d835aa8606c2b29e4e777baac8635zfaes_wrap(uint8_t *kek, int n, uint8_t *plain, uint8_t *cipher)
a399b7655a1d835aa8606c2b29e4e777baac8635zf /* 1) Initialize variables. */
a399b7655a1d835aa8606c2b29e4e777baac8635zf * 2) Calculate intermediate values.
a399b7655a1d835aa8606c2b29e4e777baac8635zf * For j = 0 to 5
a399b7655a1d835aa8606c2b29e4e777baac8635zf * For i=1 to n
a399b7655a1d835aa8606c2b29e4e777baac8635zf * B = AES(K, A | R[i])
a399b7655a1d835aa8606c2b29e4e777baac8635zf * A = MSB(64, B) ^ t where t = (n*j)+i
a399b7655a1d835aa8606c2b29e4e777baac8635zf * R[i] = LSB(64, B)
a399b7655a1d835aa8606c2b29e4e777baac8635zf for (j = 0; j <= 5; j++) {
a399b7655a1d835aa8606c2b29e4e777baac8635zf for (i = 1; i <= n; i++) {
a399b7655a1d835aa8606c2b29e4e777baac8635zf a[7] ^= n * j + i;
a399b7655a1d835aa8606c2b29e4e777baac8635zf * 3) Output the results.
a399b7655a1d835aa8606c2b29e4e777baac8635zf * These are already in @cipher due to the location of temporary
a399b7655a1d835aa8606c2b29e4e777baac8635zf * variables.
a399b7655a1d835aa8606c2b29e4e777baac8635zf * @kek: key encryption key (KEK)
a399b7655a1d835aa8606c2b29e4e777baac8635zf * @n: length of the wrapped key in 64-bit units; e.g., 2 = 128-bit = 16 bytes
a399b7655a1d835aa8606c2b29e4e777baac8635zf * @cipher: wrapped key to be unwrapped, (n + 1) * 64 bit
a399b7655a1d835aa8606c2b29e4e777baac8635zf * @plain: plaintext key, n * 64 bit
a399b7655a1d835aa8606c2b29e4e777baac8635zfaes_unwrap(uint8_t *kek, int n, uint8_t *cipher, uint8_t *plain)
a399b7655a1d835aa8606c2b29e4e777baac8635zf /* 1) Initialize variables. */
a399b7655a1d835aa8606c2b29e4e777baac8635zf * 2) Compute intermediate values.
a399b7655a1d835aa8606c2b29e4e777baac8635zf * For j = 5 to 0
a399b7655a1d835aa8606c2b29e4e777baac8635zf * For i = n to 1
a399b7655a1d835aa8606c2b29e4e777baac8635zf * B = AES-1(K, (A ^ t) | R[i]) where t = n*j+i
a399b7655a1d835aa8606c2b29e4e777baac8635zf * A = MSB(64, B)
a399b7655a1d835aa8606c2b29e4e777baac8635zf * R[i] = LSB(64, B)
a399b7655a1d835aa8606c2b29e4e777baac8635zf for (j = 5; j >= 0; j--) {
a399b7655a1d835aa8606c2b29e4e777baac8635zf for (i = n; i >= 1; i--) {
a399b7655a1d835aa8606c2b29e4e777baac8635zf b[7] ^= n * j + i;
a399b7655a1d835aa8606c2b29e4e777baac8635zf * 3) Output results.
a399b7655a1d835aa8606c2b29e4e777baac8635zf * These are already in @plain due to the location of temporary
a399b7655a1d835aa8606c2b29e4e777baac8635zf * variables. Just verify that the IV matches with the expected value.
a399b7655a1d835aa8606c2b29e4e777baac8635zf for (i = 0; i < 8; i++) {
a399b7655a1d835aa8606c2b29e4e777baac8635zf if (a[i] != 0xa6) {
a399b7655a1d835aa8606c2b29e4e777baac8635zf return (-1);
a399b7655a1d835aa8606c2b29e4e777baac8635zf return (0);
a399b7655a1d835aa8606c2b29e4e777baac8635zf/* RFC 2104 */
a399b7655a1d835aa8606c2b29e4e777baac8635zf unsigned char *data, unsigned int data_len, unsigned char *mac)
4d90dd0ecdace5438d0a722068b380d85fd8cea5Quaker Fang (void) HMAC(EVP_sha1(), key, key_len, data, data_len, mac, &mac_len);
a399b7655a1d835aa8606c2b29e4e777baac8635zfhmac_sha1_vector(unsigned char *key, unsigned int key_len, size_t num_elem,
a399b7655a1d835aa8606c2b29e4e777baac8635zf unsigned char *addr[], unsigned int *len, unsigned char *mac)
a399b7655a1d835aa8606c2b29e4e777baac8635zf for (i = 0; i < num_elem; i ++)
a399b7655a1d835aa8606c2b29e4e777baac8635zf for (i = 0; i < num_elem; i ++) {
a399b7655a1d835aa8606c2b29e4e777baac8635zfpbkdf2_sha1(char *passphrase, char *ssid, size_t ssid_len, int iterations,
4d90dd0ecdace5438d0a722068b380d85fd8cea5Quaker Fang (void) PKCS5_PBKDF2_HMAC_SHA1(passphrase, -1, (unsigned char *)ssid,
a399b7655a1d835aa8606c2b29e4e777baac8635zfrc4(uint8_t *buf, size_t len, uint8_t *key, size_t key_len)
a399b7655a1d835aa8606c2b29e4e777baac8635zfhmac_md5_vector(uint8_t *key, size_t key_len, size_t num_elem,
a399b7655a1d835aa8606c2b29e4e777baac8635zf for (i = 0; i < num_elem; i ++)
a399b7655a1d835aa8606c2b29e4e777baac8635zf for (i = 0; i < num_elem; i ++) {
a399b7655a1d835aa8606c2b29e4e777baac8635zf/* RFC 2104 */
4d90dd0ecdace5438d0a722068b380d85fd8cea5Quaker Fang (void) HMAC(EVP_md5(), key, key_len, data, data_len, mac, &mac_len);