xref: /openbsd-src/lib/libcrypto/aes/aes.c (revision 5acf4ca03be66e876e85e64f62bc19fe5e9154a6)
1 /* $OpenBSD: aes.c,v 1.2 2024/03/28 12:52:58 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 static const unsigned char aes_wrap_default_iv[] = {
59 	0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6,
60 };
61 
62 #ifdef HAVE_AES_CBC_ENCRYPT_INTERNAL
63 void aes_cbc_encrypt_internal(const unsigned char *in, unsigned char *out,
64     size_t len, const AES_KEY *key, unsigned char *ivec, const int enc);
65 
66 #else
67 static inline void
68 aes_cbc_encrypt_internal(const unsigned char *in, unsigned char *out,
69     size_t len, const AES_KEY *key, unsigned char *ivec, const int enc)
70 {
71 	if (enc)
72 		CRYPTO_cbc128_encrypt(in, out, len, key, ivec,
73 		    (block128_f)AES_encrypt);
74 	else
75 		CRYPTO_cbc128_decrypt(in, out, len, key, ivec,
76 		    (block128_f)AES_decrypt);
77 }
78 #endif
79 
80 void
81 AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
82     size_t len, const AES_KEY *key, unsigned char *ivec, const int enc)
83 {
84 	aes_cbc_encrypt_internal(in, out, len, key, ivec, enc);
85 }
86 
87 /*
88  * The input and output encrypted as though 128bit cfb mode is being
89  * used.  The extra state information to record how much of the
90  * 128bit block we have used is contained in *num;
91  */
92 
93 void
94 AES_cfb128_encrypt(const unsigned char *in, unsigned char *out, size_t length,
95     const AES_KEY *key, unsigned char *ivec, int *num, const int enc)
96 {
97 	CRYPTO_cfb128_encrypt(in, out, length, key, ivec, num, enc,
98 	    (block128_f)AES_encrypt);
99 }
100 
101 /* N.B. This expects the input to be packed, MS bit first */
102 void
103 AES_cfb1_encrypt(const unsigned char *in, unsigned char *out, size_t length,
104     const AES_KEY *key, unsigned char *ivec, int *num, const int enc)
105 {
106 	CRYPTO_cfb128_1_encrypt(in, out, length, key, ivec, num, enc,
107 	    (block128_f)AES_encrypt);
108 }
109 
110 void
111 AES_cfb8_encrypt(const unsigned char *in, unsigned char *out, size_t length,
112     const AES_KEY *key, unsigned char *ivec, int *num, const int enc)
113 {
114 	CRYPTO_cfb128_8_encrypt(in, out, length, key, ivec, num, enc,
115 	    (block128_f)AES_encrypt);
116 }
117 
118 void
119 AES_ctr128_encrypt(const unsigned char *in, unsigned char *out,
120     size_t length, const AES_KEY *key, unsigned char ivec[AES_BLOCK_SIZE],
121     unsigned char ecount_buf[AES_BLOCK_SIZE], unsigned int *num)
122 {
123 	CRYPTO_ctr128_encrypt(in, out, length, key, ivec, ecount_buf, num,
124 	    (block128_f)AES_encrypt);
125 }
126 
127 void
128 AES_ecb_encrypt(const unsigned char *in, unsigned char *out,
129     const AES_KEY *key, const int enc)
130 {
131 	if (AES_ENCRYPT == enc)
132 		AES_encrypt(in, out, key);
133 	else
134 		AES_decrypt(in, out, key);
135 }
136 
137 void
138 AES_ofb128_encrypt(const unsigned char *in, unsigned char *out, size_t length,
139     const AES_KEY *key, unsigned char *ivec, int *num)
140 {
141 	CRYPTO_ofb128_encrypt(in, out, length, key, ivec, num,
142 	    (block128_f)AES_encrypt);
143 }
144 
145 int
146 AES_wrap_key(AES_KEY *key, const unsigned char *iv, unsigned char *out,
147     const unsigned char *in, unsigned int inlen)
148 {
149 	unsigned char *A, B[16], *R;
150 	unsigned int i, j, t;
151 
152 	if ((inlen & 0x7) || (inlen < 16))
153 		return -1;
154 	A = B;
155 	t = 1;
156 	memmove(out + 8, in, inlen);
157 	if (!iv)
158 		iv = aes_wrap_default_iv;
159 
160 	memcpy(A, iv, 8);
161 
162 	for (j = 0; j < 6; j++) {
163 		R = out + 8;
164 		for (i = 0; i < inlen; i += 8, t++, R += 8) {
165 			memcpy(B + 8, R, 8);
166 			AES_encrypt(B, B, key);
167 			A[7] ^= (unsigned char)(t & 0xff);
168 			if (t > 0xff) {
169 				A[6] ^= (unsigned char)((t >> 8) & 0xff);
170 				A[5] ^= (unsigned char)((t >> 16) & 0xff);
171 				A[4] ^= (unsigned char)((t >> 24) & 0xff);
172 			}
173 			memcpy(R, B + 8, 8);
174 		}
175 	}
176 	memcpy(out, A, 8);
177 	return inlen + 8;
178 }
179 
180 int
181 AES_unwrap_key(AES_KEY *key, const unsigned char *iv, unsigned char *out,
182     const unsigned char *in, unsigned int inlen)
183 {
184 	unsigned char *A, B[16], *R;
185 	unsigned int i, j, t;
186 
187 	if ((inlen & 0x7) || (inlen < 24))
188 		return -1;
189 	inlen -= 8;
190 	A = B;
191 	t = 6 * (inlen >> 3);
192 	memcpy(A, in, 8);
193 	memmove(out, in + 8, inlen);
194 	for (j = 0; j < 6; j++) {
195 		R = out + inlen - 8;
196 		for (i = 0; i < inlen; i += 8, t--, R -= 8) {
197 			A[7] ^= (unsigned char)(t & 0xff);
198 			if (t > 0xff) {
199 				A[6] ^= (unsigned char)((t >> 8) & 0xff);
200 				A[5] ^= (unsigned char)((t >> 16) & 0xff);
201 				A[4] ^= (unsigned char)((t >> 24) & 0xff);
202 			}
203 			memcpy(B + 8, R, 8);
204 			AES_decrypt(B, B, key);
205 			memcpy(R, B + 8, 8);
206 		}
207 	}
208 	if (!iv)
209 		iv = aes_wrap_default_iv;
210 	if (memcmp(A, iv, 8)) {
211 		explicit_bzero(out, inlen);
212 		return 0;
213 	}
214 	return inlen;
215 }
216