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 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 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 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 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 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 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 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 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 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 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