1*12720SWyllys.Ingersoll@Sun.COM /*
2*12720SWyllys.Ingersoll@Sun.COM * CDDL HEADER START
3*12720SWyllys.Ingersoll@Sun.COM *
4*12720SWyllys.Ingersoll@Sun.COM * The contents of this file are subject to the terms of the
5*12720SWyllys.Ingersoll@Sun.COM * Common Development and Distribution License (the "License").
6*12720SWyllys.Ingersoll@Sun.COM * You may not use this file except in compliance with the License.
7*12720SWyllys.Ingersoll@Sun.COM *
8*12720SWyllys.Ingersoll@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*12720SWyllys.Ingersoll@Sun.COM * or http://www.opensolaris.org/os/licensing.
10*12720SWyllys.Ingersoll@Sun.COM * See the License for the specific language governing permissions
11*12720SWyllys.Ingersoll@Sun.COM * and limitations under the License.
12*12720SWyllys.Ingersoll@Sun.COM *
13*12720SWyllys.Ingersoll@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
14*12720SWyllys.Ingersoll@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*12720SWyllys.Ingersoll@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
16*12720SWyllys.Ingersoll@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
17*12720SWyllys.Ingersoll@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
18*12720SWyllys.Ingersoll@Sun.COM *
19*12720SWyllys.Ingersoll@Sun.COM * CDDL HEADER END
20*12720SWyllys.Ingersoll@Sun.COM */
21*12720SWyllys.Ingersoll@Sun.COM
22*12720SWyllys.Ingersoll@Sun.COM /*
23*12720SWyllys.Ingersoll@Sun.COM * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24*12720SWyllys.Ingersoll@Sun.COM */
25*12720SWyllys.Ingersoll@Sun.COM
26*12720SWyllys.Ingersoll@Sun.COM #if !defined(K_SOLARIS_PLATFORM) || defined(SOLARIS10)
27*12720SWyllys.Ingersoll@Sun.COM #include "rijndael.h"
28*12720SWyllys.Ingersoll@Sun.COM #else
29*12720SWyllys.Ingersoll@Sun.COM #include <stdlib.h>
30*12720SWyllys.Ingersoll@Sun.COM #include <aes_impl.h>
31*12720SWyllys.Ingersoll@Sun.COM #endif
32*12720SWyllys.Ingersoll@Sun.COM
33*12720SWyllys.Ingersoll@Sun.COM #ifdef METAWARE
34*12720SWyllys.Ingersoll@Sun.COM #include "sizet.h"
35*12720SWyllys.Ingersoll@Sun.COM typedef unsigned char uint8_t;
36*12720SWyllys.Ingersoll@Sun.COM typedef unsigned short uint16_t;
37*12720SWyllys.Ingersoll@Sun.COM typedef unsigned int uint32_t;
38*12720SWyllys.Ingersoll@Sun.COM typedef unsigned long long uint64_t;
39*12720SWyllys.Ingersoll@Sun.COM #include <string.h>
40*12720SWyllys.Ingersoll@Sun.COM #else
41*12720SWyllys.Ingersoll@Sun.COM #ifndef WIN32
42*12720SWyllys.Ingersoll@Sun.COM #include <strings.h>
43*12720SWyllys.Ingersoll@Sun.COM #endif
44*12720SWyllys.Ingersoll@Sun.COM #endif
45*12720SWyllys.Ingersoll@Sun.COM
46*12720SWyllys.Ingersoll@Sun.COM #include "KMSAgentAESKeyWrap.h"
47*12720SWyllys.Ingersoll@Sun.COM
48*12720SWyllys.Ingersoll@Sun.COM #ifndef TRUE
49*12720SWyllys.Ingersoll@Sun.COM #define TRUE 1
50*12720SWyllys.Ingersoll@Sun.COM #endif
51*12720SWyllys.Ingersoll@Sun.COM
52*12720SWyllys.Ingersoll@Sun.COM #ifndef FALSE
53*12720SWyllys.Ingersoll@Sun.COM #define FALSE 0
54*12720SWyllys.Ingersoll@Sun.COM #endif
55*12720SWyllys.Ingersoll@Sun.COM
56*12720SWyllys.Ingersoll@Sun.COM #ifdef WIN32
57*12720SWyllys.Ingersoll@Sun.COM #define ovbcopy(x, y, z) memmove(y, x, z);
58*12720SWyllys.Ingersoll@Sun.COM #else
59*12720SWyllys.Ingersoll@Sun.COM #define ovbcopy(x, y, z) bcopy(x, y, z);
60*12720SWyllys.Ingersoll@Sun.COM #endif
61*12720SWyllys.Ingersoll@Sun.COM
62*12720SWyllys.Ingersoll@Sun.COM #ifndef K_SOLARIS_PLATFORM
63*12720SWyllys.Ingersoll@Sun.COM /* similar to iovec except that it accepts const pointers */
64*12720SWyllys.Ingersoll@Sun.COM struct vector {
65*12720SWyllys.Ingersoll@Sun.COM const void *base;
66*12720SWyllys.Ingersoll@Sun.COM size_t len;
67*12720SWyllys.Ingersoll@Sun.COM };
68*12720SWyllys.Ingersoll@Sun.COM
69*12720SWyllys.Ingersoll@Sun.COM #ifdef METAWARE
70*12720SWyllys.Ingersoll@Sun.COM #define bcopy(s1, s2, n) memcpy(s2, s1, n)
71*12720SWyllys.Ingersoll@Sun.COM #endif
72*12720SWyllys.Ingersoll@Sun.COM
73*12720SWyllys.Ingersoll@Sun.COM /*
74*12720SWyllys.Ingersoll@Sun.COM * AES Key Wrap (see RFC 3394).
75*12720SWyllys.Ingersoll@Sun.COM */
76*12720SWyllys.Ingersoll@Sun.COM #endif /* K_SOLARIS_PLATFORM */
77*12720SWyllys.Ingersoll@Sun.COM
78*12720SWyllys.Ingersoll@Sun.COM static const uint8_t aes_key_wrap_iv[8] =
79*12720SWyllys.Ingersoll@Sun.COM { 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6 };
80*12720SWyllys.Ingersoll@Sun.COM
aes_key_wrap(const uint8_t * kek,size_t kek_len,const uint8_t * pt,size_t len,uint8_t * ct)81*12720SWyllys.Ingersoll@Sun.COM void aes_key_wrap (const uint8_t *kek,
82*12720SWyllys.Ingersoll@Sun.COM size_t kek_len,
83*12720SWyllys.Ingersoll@Sun.COM const uint8_t *pt,
84*12720SWyllys.Ingersoll@Sun.COM size_t len,
85*12720SWyllys.Ingersoll@Sun.COM uint8_t *ct)
86*12720SWyllys.Ingersoll@Sun.COM {
87*12720SWyllys.Ingersoll@Sun.COM #if !defined(K_SOLARIS_PLATFORM) || defined(SOLARIS10)
88*12720SWyllys.Ingersoll@Sun.COM rijndael_ctx ctx;
89*12720SWyllys.Ingersoll@Sun.COM #else
90*12720SWyllys.Ingersoll@Sun.COM void *ks;
91*12720SWyllys.Ingersoll@Sun.COM size_t ks_size;
92*12720SWyllys.Ingersoll@Sun.COM #endif
93*12720SWyllys.Ingersoll@Sun.COM uint8_t *a, *r, ar[16], t, b[16];
94*12720SWyllys.Ingersoll@Sun.COM size_t i;
95*12720SWyllys.Ingersoll@Sun.COM int j;
96*12720SWyllys.Ingersoll@Sun.COM
97*12720SWyllys.Ingersoll@Sun.COM /*
98*12720SWyllys.Ingersoll@Sun.COM * Only allow lengths for 't' values that fit within a byte. This
99*12720SWyllys.Ingersoll@Sun.COM * covers all reasonable uses of AES Key Wrap
100*12720SWyllys.Ingersoll@Sun.COM */
101*12720SWyllys.Ingersoll@Sun.COM if (len > (255 / 6)) {
102*12720SWyllys.Ingersoll@Sun.COM return;
103*12720SWyllys.Ingersoll@Sun.COM }
104*12720SWyllys.Ingersoll@Sun.COM
105*12720SWyllys.Ingersoll@Sun.COM /* allow ciphertext and plaintext to overlap (ct == pt) */
106*12720SWyllys.Ingersoll@Sun.COM ovbcopy(pt, ct + 8, len * 8);
107*12720SWyllys.Ingersoll@Sun.COM
108*12720SWyllys.Ingersoll@Sun.COM a = ct;
109*12720SWyllys.Ingersoll@Sun.COM memcpy(a, aes_key_wrap_iv, 8); /* default IV */
110*12720SWyllys.Ingersoll@Sun.COM
111*12720SWyllys.Ingersoll@Sun.COM #if !defined(K_SOLARIS_PLATFORM) || defined(SOLARIS10)
112*12720SWyllys.Ingersoll@Sun.COM rijndael_set_key_enc_only(&ctx, (uint8_t *)kek, kek_len * 8);
113*12720SWyllys.Ingersoll@Sun.COM #else
114*12720SWyllys.Ingersoll@Sun.COM ks = aes_alloc_keysched(&ks_size, 0);
115*12720SWyllys.Ingersoll@Sun.COM if (ks == NULL)
116*12720SWyllys.Ingersoll@Sun.COM return;
117*12720SWyllys.Ingersoll@Sun.COM aes_init_keysched(kek, kek_len * 8, ks);
118*12720SWyllys.Ingersoll@Sun.COM #endif
119*12720SWyllys.Ingersoll@Sun.COM
120*12720SWyllys.Ingersoll@Sun.COM for (j = 0, t = 1; j < 6; j++) {
121*12720SWyllys.Ingersoll@Sun.COM r = ct + 8;
122*12720SWyllys.Ingersoll@Sun.COM for (i = 0; i < len; i++, t++) {
123*12720SWyllys.Ingersoll@Sun.COM memcpy(ar, a, 8);
124*12720SWyllys.Ingersoll@Sun.COM memcpy(ar + 8, r, 8);
125*12720SWyllys.Ingersoll@Sun.COM #if !defined(K_SOLARIS_PLATFORM) || defined(SOLARIS10)
126*12720SWyllys.Ingersoll@Sun.COM rijndael_encrypt(&ctx, ar, b);
127*12720SWyllys.Ingersoll@Sun.COM #else
128*12720SWyllys.Ingersoll@Sun.COM (void) aes_encrypt_block(ks, ar, b);
129*12720SWyllys.Ingersoll@Sun.COM #endif
130*12720SWyllys.Ingersoll@Sun.COM
131*12720SWyllys.Ingersoll@Sun.COM b[7] ^= t;
132*12720SWyllys.Ingersoll@Sun.COM memcpy(a, &b[0], 8);
133*12720SWyllys.Ingersoll@Sun.COM memcpy(r, &b[8], 8);
134*12720SWyllys.Ingersoll@Sun.COM
135*12720SWyllys.Ingersoll@Sun.COM r += 8;
136*12720SWyllys.Ingersoll@Sun.COM }
137*12720SWyllys.Ingersoll@Sun.COM }
138*12720SWyllys.Ingersoll@Sun.COM #if defined(K_SOLARIS_PLATFORM) && !defined(SOLARIS10)
139*12720SWyllys.Ingersoll@Sun.COM free(ks);
140*12720SWyllys.Ingersoll@Sun.COM #endif
141*12720SWyllys.Ingersoll@Sun.COM }
142*12720SWyllys.Ingersoll@Sun.COM
aes_key_unwrap(const uint8_t * kek,size_t kek_len,const uint8_t * ct,uint8_t * pt,size_t len)143*12720SWyllys.Ingersoll@Sun.COM int aes_key_unwrap (const uint8_t *kek,
144*12720SWyllys.Ingersoll@Sun.COM size_t kek_len,
145*12720SWyllys.Ingersoll@Sun.COM const uint8_t *ct,
146*12720SWyllys.Ingersoll@Sun.COM uint8_t *pt,
147*12720SWyllys.Ingersoll@Sun.COM size_t len)
148*12720SWyllys.Ingersoll@Sun.COM {
149*12720SWyllys.Ingersoll@Sun.COM #if !defined(K_SOLARIS_PLATFORM) || defined(SOLARIS10)
150*12720SWyllys.Ingersoll@Sun.COM rijndael_ctx ctx;
151*12720SWyllys.Ingersoll@Sun.COM #else
152*12720SWyllys.Ingersoll@Sun.COM void *ks;
153*12720SWyllys.Ingersoll@Sun.COM size_t ks_size;
154*12720SWyllys.Ingersoll@Sun.COM #endif
155*12720SWyllys.Ingersoll@Sun.COM uint8_t a[8], *r, b[16], t, ar[16];
156*12720SWyllys.Ingersoll@Sun.COM size_t i;
157*12720SWyllys.Ingersoll@Sun.COM int j;
158*12720SWyllys.Ingersoll@Sun.COM
159*12720SWyllys.Ingersoll@Sun.COM /*
160*12720SWyllys.Ingersoll@Sun.COM * Only allow lengths for 't' values that fit within a byte. This
161*12720SWyllys.Ingersoll@Sun.COM * covers all reasonable uses of AES Key Wrap
162*12720SWyllys.Ingersoll@Sun.COM */
163*12720SWyllys.Ingersoll@Sun.COM if (len > (255 / 6)) {
164*12720SWyllys.Ingersoll@Sun.COM return (-1);
165*12720SWyllys.Ingersoll@Sun.COM }
166*12720SWyllys.Ingersoll@Sun.COM
167*12720SWyllys.Ingersoll@Sun.COM memcpy(a, ct, 8);
168*12720SWyllys.Ingersoll@Sun.COM /* allow ciphertext and plaintext to overlap (ct == pt) */
169*12720SWyllys.Ingersoll@Sun.COM ovbcopy(ct + 8, pt, len * 8);
170*12720SWyllys.Ingersoll@Sun.COM
171*12720SWyllys.Ingersoll@Sun.COM #if !defined(K_SOLARIS_PLATFORM) || defined(SOLARIS10)
172*12720SWyllys.Ingersoll@Sun.COM rijndael_set_key(&ctx, (uint8_t *)kek, kek_len * 8);
173*12720SWyllys.Ingersoll@Sun.COM #else
174*12720SWyllys.Ingersoll@Sun.COM ks = aes_alloc_keysched(&ks_size, 0);
175*12720SWyllys.Ingersoll@Sun.COM if (ks == NULL)
176*12720SWyllys.Ingersoll@Sun.COM return (-1);
177*12720SWyllys.Ingersoll@Sun.COM aes_init_keysched(kek, kek_len * 8, ks);
178*12720SWyllys.Ingersoll@Sun.COM #endif
179*12720SWyllys.Ingersoll@Sun.COM
180*12720SWyllys.Ingersoll@Sun.COM for (j = 0, t = 6 * len; j < 6; j++) {
181*12720SWyllys.Ingersoll@Sun.COM r = pt + (len - 1) * 8;
182*12720SWyllys.Ingersoll@Sun.COM for (i = 0; i < len; i++, t--) {
183*12720SWyllys.Ingersoll@Sun.COM memcpy(&ar[0], a, 8);
184*12720SWyllys.Ingersoll@Sun.COM ar[7] ^= t;
185*12720SWyllys.Ingersoll@Sun.COM memcpy(&ar[8], r, 8);
186*12720SWyllys.Ingersoll@Sun.COM #if !defined(K_SOLARIS_PLATFORM) || defined(SOLARIS10)
187*12720SWyllys.Ingersoll@Sun.COM rijndael_decrypt(&ctx, ar, b);
188*12720SWyllys.Ingersoll@Sun.COM #else
189*12720SWyllys.Ingersoll@Sun.COM (void) aes_decrypt_block(ks, ar, b);
190*12720SWyllys.Ingersoll@Sun.COM #endif
191*12720SWyllys.Ingersoll@Sun.COM memcpy(a, b, 8);
192*12720SWyllys.Ingersoll@Sun.COM memcpy(r, b + 8, 8);
193*12720SWyllys.Ingersoll@Sun.COM r -= 8;
194*12720SWyllys.Ingersoll@Sun.COM }
195*12720SWyllys.Ingersoll@Sun.COM }
196*12720SWyllys.Ingersoll@Sun.COM #if defined(K_SOLARIS_PLATFORM) && !defined(SOLARIS10)
197*12720SWyllys.Ingersoll@Sun.COM free(ks);
198*12720SWyllys.Ingersoll@Sun.COM #endif
199*12720SWyllys.Ingersoll@Sun.COM
200*12720SWyllys.Ingersoll@Sun.COM return memcmp(a, aes_key_wrap_iv, 8) != 0;
201*12720SWyllys.Ingersoll@Sun.COM }
202