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