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