1 /* $OpenBSD: aes.c,v 1.3 2024/03/30 05:14:12 joshua 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 LCRYPTO_ALIAS(AES_cbc_encrypt); 87 88 /* 89 * The input and output encrypted as though 128bit cfb mode is being 90 * used. The extra state information to record how much of the 91 * 128bit block we have used is contained in *num; 92 */ 93 94 void 95 AES_cfb128_encrypt(const unsigned char *in, unsigned char *out, size_t length, 96 const AES_KEY *key, unsigned char *ivec, int *num, const int enc) 97 { 98 CRYPTO_cfb128_encrypt(in, out, length, key, ivec, num, enc, 99 (block128_f)AES_encrypt); 100 } 101 LCRYPTO_ALIAS(AES_cfb128_encrypt); 102 103 /* N.B. This expects the input to be packed, MS bit first */ 104 void 105 AES_cfb1_encrypt(const unsigned char *in, unsigned char *out, size_t length, 106 const AES_KEY *key, unsigned char *ivec, int *num, const int enc) 107 { 108 CRYPTO_cfb128_1_encrypt(in, out, length, key, ivec, num, enc, 109 (block128_f)AES_encrypt); 110 } 111 LCRYPTO_ALIAS(AES_cfb1_encrypt); 112 113 void 114 AES_cfb8_encrypt(const unsigned char *in, unsigned char *out, size_t length, 115 const AES_KEY *key, unsigned char *ivec, int *num, const int enc) 116 { 117 CRYPTO_cfb128_8_encrypt(in, out, length, key, ivec, num, enc, 118 (block128_f)AES_encrypt); 119 } 120 LCRYPTO_ALIAS(AES_cfb8_encrypt); 121 122 void 123 AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, 124 size_t length, const AES_KEY *key, unsigned char ivec[AES_BLOCK_SIZE], 125 unsigned char ecount_buf[AES_BLOCK_SIZE], unsigned int *num) 126 { 127 CRYPTO_ctr128_encrypt(in, out, length, key, ivec, ecount_buf, num, 128 (block128_f)AES_encrypt); 129 } 130 LCRYPTO_ALIAS(AES_ctr128_encrypt); 131 132 void 133 AES_ecb_encrypt(const unsigned char *in, unsigned char *out, 134 const AES_KEY *key, const int enc) 135 { 136 if (AES_ENCRYPT == enc) 137 AES_encrypt(in, out, key); 138 else 139 AES_decrypt(in, out, key); 140 } 141 LCRYPTO_ALIAS(AES_ecb_encrypt); 142 143 void 144 AES_ofb128_encrypt(const unsigned char *in, unsigned char *out, size_t length, 145 const AES_KEY *key, unsigned char *ivec, int *num) 146 { 147 CRYPTO_ofb128_encrypt(in, out, length, key, ivec, num, 148 (block128_f)AES_encrypt); 149 } 150 LCRYPTO_ALIAS(AES_ofb128_encrypt); 151 152 int 153 AES_wrap_key(AES_KEY *key, const unsigned char *iv, unsigned char *out, 154 const unsigned char *in, unsigned int inlen) 155 { 156 unsigned char *A, B[16], *R; 157 unsigned int i, j, t; 158 159 if ((inlen & 0x7) || (inlen < 16)) 160 return -1; 161 A = B; 162 t = 1; 163 memmove(out + 8, in, inlen); 164 if (!iv) 165 iv = aes_wrap_default_iv; 166 167 memcpy(A, iv, 8); 168 169 for (j = 0; j < 6; j++) { 170 R = out + 8; 171 for (i = 0; i < inlen; i += 8, t++, R += 8) { 172 memcpy(B + 8, R, 8); 173 AES_encrypt(B, B, key); 174 A[7] ^= (unsigned char)(t & 0xff); 175 if (t > 0xff) { 176 A[6] ^= (unsigned char)((t >> 8) & 0xff); 177 A[5] ^= (unsigned char)((t >> 16) & 0xff); 178 A[4] ^= (unsigned char)((t >> 24) & 0xff); 179 } 180 memcpy(R, B + 8, 8); 181 } 182 } 183 memcpy(out, A, 8); 184 return inlen + 8; 185 } 186 LCRYPTO_ALIAS(AES_wrap_key); 187 188 int 189 AES_unwrap_key(AES_KEY *key, const unsigned char *iv, unsigned char *out, 190 const unsigned char *in, unsigned int inlen) 191 { 192 unsigned char *A, B[16], *R; 193 unsigned int i, j, t; 194 195 if ((inlen & 0x7) || (inlen < 24)) 196 return -1; 197 inlen -= 8; 198 A = B; 199 t = 6 * (inlen >> 3); 200 memcpy(A, in, 8); 201 memmove(out, in + 8, inlen); 202 for (j = 0; j < 6; j++) { 203 R = out + inlen - 8; 204 for (i = 0; i < inlen; i += 8, t--, R -= 8) { 205 A[7] ^= (unsigned char)(t & 0xff); 206 if (t > 0xff) { 207 A[6] ^= (unsigned char)((t >> 8) & 0xff); 208 A[5] ^= (unsigned char)((t >> 16) & 0xff); 209 A[4] ^= (unsigned char)((t >> 24) & 0xff); 210 } 211 memcpy(B + 8, R, 8); 212 AES_decrypt(B, B, key); 213 memcpy(R, B + 8, 8); 214 } 215 } 216 if (!iv) 217 iv = aes_wrap_default_iv; 218 if (memcmp(A, iv, 8)) { 219 explicit_bzero(out, inlen); 220 return 0; 221 } 222 return inlen; 223 } 224 LCRYPTO_ALIAS(AES_unwrap_key); 225