iPXE
aes_wrap.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2009 Joshua Oreman <oremanj@rwcr.net>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  */
19 
20 FILE_LICENCE ( GPL2_OR_LATER );
21 
22 #include <stdlib.h>
23 #include <string.h>
24 #include <ipxe/crypto.h>
25 #include <ipxe/aes.h>
26 
27 /**
28  * Wrap a key or other data using AES Key Wrap (RFC 3394)
29  *
30  * @v kek Key Encryption Key, 16 bytes
31  * @v src Data to encrypt
32  * @v nblk Number of 8-byte blocks in @a data
33  * @ret dest Encrypted data (8 bytes longer than input)
34  *
35  * The algorithm is implemented such that @a src and @a dest may point
36  * to the same buffer.
37  */
38 int aes_wrap ( const void *kek, const void *src, void *dest, int nblk )
39 {
40  u8 *A = dest;
41  u8 B[16];
42  u8 *R;
43  int i, j;
44  void *aes_ctx = malloc ( AES_CTX_SIZE );
45 
46  if ( ! aes_ctx )
47  return -1;
48 
49  cipher_setkey ( &aes_algorithm, aes_ctx, kek, 16 );
50 
51  /* Set up */
52  memset ( A, 0xA6, 8 );
53  memmove ( dest + 8, src, nblk * 8 );
54 
55  /* Wrap */
56  for ( j = 0; j < 6; j++ ) {
57  R = dest + 8;
58  for ( i = 1; i <= nblk; i++ ) {
59  memcpy ( B, A, 8 );
60  memcpy ( B + 8, R, 8 );
61  cipher_encrypt ( &aes_algorithm, aes_ctx, B, B, 16 );
62  memcpy ( A, B, 8 );
63  A[7] ^= ( nblk * j ) + i;
64  memcpy ( R, B + 8, 8 );
65  R += 8;
66  }
67  }
68 
69  free ( aes_ctx );
70  return 0;
71 }
72 
73 /**
74  * Unwrap a key or other data using AES Key Wrap (RFC 3394)
75  *
76  * @v kek Key Encryption Key, 16 bytes
77  * @v src Data to decrypt
78  * @v nblk Number of 8-byte blocks in @e plaintext key
79  * @ret dest Decrypted data (8 bytes shorter than input)
80  * @ret rc Zero on success, nonzero on IV mismatch
81  *
82  * The algorithm is implemented such that @a src and @a dest may point
83  * to the same buffer.
84  */
85 int aes_unwrap ( const void *kek, const void *src, void *dest, int nblk )
86 {
87  u8 A[8], B[16];
88  u8 *R;
89  int i, j;
90  void *aes_ctx = malloc ( AES_CTX_SIZE );
91 
92  if ( ! aes_ctx )
93  return -1;
94 
95  cipher_setkey ( &aes_algorithm, aes_ctx, kek, 16 );
96 
97  /* Set up */
98  memcpy ( A, src, 8 );
99  memmove ( dest, src + 8, nblk * 8 );
100 
101  /* Unwrap */
102  for ( j = 5; j >= 0; j-- ) {
103  R = dest + ( nblk - 1 ) * 8;
104  for ( i = nblk; i >= 1; i-- ) {
105  memcpy ( B, A, 8 );
106  memcpy ( B + 8, R, 8 );
107  B[7] ^= ( nblk * j ) + i;
108  cipher_decrypt ( &aes_algorithm, aes_ctx, B, B, 16 );
109  memcpy ( A, B, 8 );
110  memcpy ( R, B + 8, 8 );
111  R -= 8;
112  }
113  }
114 
115  free ( aes_ctx );
116 
117  /* Check IV */
118  for ( i = 0; i < 8; i++ ) {
119  if ( A[i] != 0xA6 )
120  return -1;
121  }
122 
123  return 0;
124 }
#define AES_CTX_SIZE
AES context size.
Definition: aes.h:45
Cryptographic API.
struct cipher_algorithm aes_algorithm
Basic AES algorithm.
Definition: aes.c:792
#define cipher_encrypt(cipher, ctx, src, dst, len)
Definition: crypto.h:202
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static void * dest
Definition: strings.h:176
static __always_inline void off_t userptr_t src
Definition: efi_uaccess.h:66
AES algorithm.
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
u8 kek[WPA_KEK_LEN]
EAPOL-Key Key Encryption Key (KEK)
Definition: wpa.h:31
#define cipher_decrypt(cipher, ctx, src, dst, len)
Definition: crypto.h:212
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
int aes_wrap(const void *kek, const void *src, void *dest, int nblk)
Wrap a key or other data using AES Key Wrap (RFC 3394)
Definition: aes_wrap.c:38
void * memmove(void *dest, const void *src, size_t len) __nonnull
int aes_unwrap(const void *kek, const void *src, void *dest, int nblk)
Unwrap a key or other data using AES Key Wrap (RFC 3394)
Definition: aes_wrap.c:85
String functions.
uint8_t u8
Definition: stdint.h:19
FILE_LICENCE(GPL2_OR_LATER)
static int cipher_setkey(struct cipher_algorithm *cipher, void *ctx, const void *key, size_t keylen)
Definition: crypto.h:187
void * memset(void *dest, int character, size_t len) __nonnull