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