|
|
1.1 root 1: /*
2: * Copyright (c) 2009 Joshua Oreman <[email protected]>.
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., 675 Mass Ave, Cambridge, MA 02139, USA.
17: */
18:
19: FILE_LICENCE ( GPL2_OR_LATER );
20:
21: #include <stdlib.h>
22: #include <string.h>
23: #include <ipxe/crypto.h>
24: #include <ipxe/aes.h>
25:
26: /**
27: * Wrap a key or other data using AES Key Wrap (RFC 3394)
28: *
29: * @v kek Key Encryption Key, 16 bytes
30: * @v src Data to encrypt
31: * @v nblk Number of 8-byte blocks in @a data
32: * @ret dest Encrypted data (8 bytes longer than input)
33: *
34: * The algorithm is implemented such that @a src and @a dest may point
35: * to the same buffer.
36: */
37: int aes_wrap ( const void *kek, const void *src, void *dest, int nblk )
38: {
39: u8 *A = dest;
40: u8 B[16];
41: u8 *R;
42: int i, j;
43: void *aes_ctx = malloc ( AES_CTX_SIZE );
44:
45: if ( ! aes_ctx )
46: return -1;
47:
48: cipher_setkey ( &aes_algorithm, aes_ctx, kek, 16 );
49:
50: /* Set up */
51: memset ( A, 0xA6, sizeof ( A ) );
52: memmove ( dest + 8, src, nblk * 8 );
53:
54: /* Wrap */
55: for ( j = 0; j < 6; j++ ) {
56: R = dest + 8;
57: for ( i = 1; i <= nblk; i++ ) {
58: memcpy ( B, A, 8 );
59: memcpy ( B + 8, R, 8 );
60: cipher_encrypt ( &aes_algorithm, aes_ctx, B, B, 16 );
61: memcpy ( A, B, 8 );
62: A[7] ^= ( nblk * j ) + i;
63: memcpy ( R, B + 8, 8 );
64: R += 8;
65: }
66: }
67:
68: free ( aes_ctx );
69: return 0;
70: }
71:
72: /**
73: * Unwrap a key or other data using AES Key Wrap (RFC 3394)
74: *
75: * @v kek Key Encryption Key, 16 bytes
76: * @v src Data to decrypt
77: * @v nblk Number of 8-byte blocks in @e plaintext key
78: * @ret dest Decrypted data (8 bytes shorter than input)
79: * @ret rc Zero on success, nonzero on IV mismatch
80: *
81: * The algorithm is implemented such that @a src and @a dest may point
82: * to the same buffer.
83: */
84: int aes_unwrap ( const void *kek, const void *src, void *dest, int nblk )
85: {
86: u8 A[8], B[16];
87: u8 *R;
88: int i, j;
89: void *aes_ctx = malloc ( AES_CTX_SIZE );
90:
91: if ( ! aes_ctx )
92: return -1;
93:
94: cipher_setkey ( &aes_algorithm, aes_ctx, kek, 16 );
95:
96: /* Set up */
97: memcpy ( A, src, 8 );
98: memmove ( dest, src + 8, nblk * 8 );
99:
100: /* Unwrap */
101: for ( j = 5; j >= 0; j-- ) {
102: R = dest + ( nblk - 1 ) * 8;
103: for ( i = nblk; i >= 1; i-- ) {
104: memcpy ( B, A, 8 );
105: memcpy ( B + 8, R, 8 );
106: B[7] ^= ( nblk * j ) + i;
107: cipher_decrypt ( &aes_algorithm, aes_ctx, B, B, 16 );
108: memcpy ( A, B, 8 );
109: memcpy ( R, B + 8, 8 );
110: R -= 8;
111: }
112: }
113:
114: free ( aes_ctx );
115:
116: /* Check IV */
117: for ( i = 0; i < 8; i++ ) {
118: if ( A[i] != 0xA6 )
119: return -1;
120: }
121:
122: return 0;
123: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.