1 /* $OpenBSD: aes.c,v 1.4 2024/08/11 13:02:39 jsing Exp $ */
2 /* ====================================================================
3 * Copyright (c) 2002-2006 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. All advertising materials mentioning features or use of this
18 * software must display the following acknowledgment:
19 * "This product includes software developed by the OpenSSL Project
20 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
21 *
22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 * endorse or promote products derived from this software without
24 * prior written permission. For written permission, please contact
25 * openssl-core@openssl.org.
26 *
27 * 5. Products derived from this software may not be called "OpenSSL"
28 * nor may "OpenSSL" appear in their names without prior written
29 * permission of the OpenSSL Project.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 * OF THE POSSIBILITY OF SUCH DAMAGE.
48 * ====================================================================
49 *
50 */
51
52 #include <string.h>
53
54 #include <openssl/aes.h>
55 #include <openssl/bio.h>
56 #include <openssl/modes.h>
57
58 #include "crypto_arch.h"
59
60 static const unsigned char aes_wrap_default_iv[] = {
61 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6,
62 };
63
64 #ifdef HAVE_AES_CBC_ENCRYPT_INTERNAL
65 void aes_cbc_encrypt_internal(const unsigned char *in, unsigned char *out,
66 size_t len, const AES_KEY *key, unsigned char *ivec, const int enc);
67
68 #else
69 static inline void
aes_cbc_encrypt_internal(const unsigned char * in,unsigned char * out,size_t len,const AES_KEY * key,unsigned char * ivec,const int enc)70 aes_cbc_encrypt_internal(const unsigned char *in, unsigned char *out,
71 size_t len, const AES_KEY *key, unsigned char *ivec, const int enc)
72 {
73 if (enc)
74 CRYPTO_cbc128_encrypt(in, out, len, key, ivec,
75 (block128_f)AES_encrypt);
76 else
77 CRYPTO_cbc128_decrypt(in, out, len, key, ivec,
78 (block128_f)AES_decrypt);
79 }
80 #endif
81
82 void
AES_cbc_encrypt(const unsigned char * in,unsigned char * out,size_t len,const AES_KEY * key,unsigned char * ivec,const int enc)83 AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
84 size_t len, const AES_KEY *key, unsigned char *ivec, const int enc)
85 {
86 aes_cbc_encrypt_internal(in, out, len, key, ivec, enc);
87 }
88 LCRYPTO_ALIAS(AES_cbc_encrypt);
89
90 /*
91 * The input and output encrypted as though 128bit cfb mode is being
92 * used. The extra state information to record how much of the
93 * 128bit block we have used is contained in *num;
94 */
95
96 void
AES_cfb128_encrypt(const unsigned char * in,unsigned char * out,size_t length,const AES_KEY * key,unsigned char * ivec,int * num,const int enc)97 AES_cfb128_encrypt(const unsigned char *in, unsigned char *out, size_t length,
98 const AES_KEY *key, unsigned char *ivec, int *num, const int enc)
99 {
100 CRYPTO_cfb128_encrypt(in, out, length, key, ivec, num, enc,
101 (block128_f)AES_encrypt);
102 }
103 LCRYPTO_ALIAS(AES_cfb128_encrypt);
104
105 /* N.B. This expects the input to be packed, MS bit first */
106 void
AES_cfb1_encrypt(const unsigned char * in,unsigned char * out,size_t length,const AES_KEY * key,unsigned char * ivec,int * num,const int enc)107 AES_cfb1_encrypt(const unsigned char *in, unsigned char *out, size_t length,
108 const AES_KEY *key, unsigned char *ivec, int *num, const int enc)
109 {
110 CRYPTO_cfb128_1_encrypt(in, out, length, key, ivec, num, enc,
111 (block128_f)AES_encrypt);
112 }
113 LCRYPTO_ALIAS(AES_cfb1_encrypt);
114
115 void
AES_cfb8_encrypt(const unsigned char * in,unsigned char * out,size_t length,const AES_KEY * key,unsigned char * ivec,int * num,const int enc)116 AES_cfb8_encrypt(const unsigned char *in, unsigned char *out, size_t length,
117 const AES_KEY *key, unsigned char *ivec, int *num, const int enc)
118 {
119 CRYPTO_cfb128_8_encrypt(in, out, length, key, ivec, num, enc,
120 (block128_f)AES_encrypt);
121 }
122 LCRYPTO_ALIAS(AES_cfb8_encrypt);
123
124 void
AES_ctr128_encrypt(const unsigned char * in,unsigned char * out,size_t length,const AES_KEY * key,unsigned char ivec[AES_BLOCK_SIZE],unsigned char ecount_buf[AES_BLOCK_SIZE],unsigned int * num)125 AES_ctr128_encrypt(const unsigned char *in, unsigned char *out,
126 size_t length, const AES_KEY *key, unsigned char ivec[AES_BLOCK_SIZE],
127 unsigned char ecount_buf[AES_BLOCK_SIZE], unsigned int *num)
128 {
129 CRYPTO_ctr128_encrypt(in, out, length, key, ivec, ecount_buf, num,
130 (block128_f)AES_encrypt);
131 }
132 LCRYPTO_ALIAS(AES_ctr128_encrypt);
133
134 void
AES_ecb_encrypt(const unsigned char * in,unsigned char * out,const AES_KEY * key,const int enc)135 AES_ecb_encrypt(const unsigned char *in, unsigned char *out,
136 const AES_KEY *key, const int enc)
137 {
138 if (AES_ENCRYPT == enc)
139 AES_encrypt(in, out, key);
140 else
141 AES_decrypt(in, out, key);
142 }
143 LCRYPTO_ALIAS(AES_ecb_encrypt);
144
145 void
AES_ofb128_encrypt(const unsigned char * in,unsigned char * out,size_t length,const AES_KEY * key,unsigned char * ivec,int * num)146 AES_ofb128_encrypt(const unsigned char *in, unsigned char *out, size_t length,
147 const AES_KEY *key, unsigned char *ivec, int *num)
148 {
149 CRYPTO_ofb128_encrypt(in, out, length, key, ivec, num,
150 (block128_f)AES_encrypt);
151 }
152 LCRYPTO_ALIAS(AES_ofb128_encrypt);
153
154 int
AES_wrap_key(AES_KEY * key,const unsigned char * iv,unsigned char * out,const unsigned char * in,unsigned int inlen)155 AES_wrap_key(AES_KEY *key, const unsigned char *iv, unsigned char *out,
156 const unsigned char *in, unsigned int inlen)
157 {
158 unsigned char *A, B[16], *R;
159 unsigned int i, j, t;
160
161 if ((inlen & 0x7) || (inlen < 16))
162 return -1;
163 A = B;
164 t = 1;
165 memmove(out + 8, in, inlen);
166 if (!iv)
167 iv = aes_wrap_default_iv;
168
169 memcpy(A, iv, 8);
170
171 for (j = 0; j < 6; j++) {
172 R = out + 8;
173 for (i = 0; i < inlen; i += 8, t++, R += 8) {
174 memcpy(B + 8, R, 8);
175 AES_encrypt(B, B, key);
176 A[7] ^= (unsigned char)(t & 0xff);
177 if (t > 0xff) {
178 A[6] ^= (unsigned char)((t >> 8) & 0xff);
179 A[5] ^= (unsigned char)((t >> 16) & 0xff);
180 A[4] ^= (unsigned char)((t >> 24) & 0xff);
181 }
182 memcpy(R, B + 8, 8);
183 }
184 }
185 memcpy(out, A, 8);
186 return inlen + 8;
187 }
188 LCRYPTO_ALIAS(AES_wrap_key);
189
190 int
AES_unwrap_key(AES_KEY * key,const unsigned char * iv,unsigned char * out,const unsigned char * in,unsigned int inlen)191 AES_unwrap_key(AES_KEY *key, const unsigned char *iv, unsigned char *out,
192 const unsigned char *in, unsigned int inlen)
193 {
194 unsigned char *A, B[16], *R;
195 unsigned int i, j, t;
196
197 if ((inlen & 0x7) || (inlen < 24))
198 return -1;
199 inlen -= 8;
200 A = B;
201 t = 6 * (inlen >> 3);
202 memcpy(A, in, 8);
203 memmove(out, in + 8, inlen);
204 for (j = 0; j < 6; j++) {
205 R = out + inlen - 8;
206 for (i = 0; i < inlen; i += 8, t--, R -= 8) {
207 A[7] ^= (unsigned char)(t & 0xff);
208 if (t > 0xff) {
209 A[6] ^= (unsigned char)((t >> 8) & 0xff);
210 A[5] ^= (unsigned char)((t >> 16) & 0xff);
211 A[4] ^= (unsigned char)((t >> 24) & 0xff);
212 }
213 memcpy(B + 8, R, 8);
214 AES_decrypt(B, B, key);
215 memcpy(R, B + 8, 8);
216 }
217 }
218 if (!iv)
219 iv = aes_wrap_default_iv;
220 if (memcmp(A, iv, 8)) {
221 explicit_bzero(out, inlen);
222 return 0;
223 }
224 return inlen;
225 }
226 LCRYPTO_ALIAS(AES_unwrap_key);
227