1 /* 2 * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 /* 11 * AES_encrypt/AES_decrypt are deprecated - but we need to use them to implement 12 * these functions 13 */ 14 #include "internal/deprecated.h" 15 16 #include "internal/cryptlib.h" 17 18 #include <openssl/aes.h> 19 #include "aes_local.h" 20 21 /* XXX: probably some better way to do this */ 22 #if defined(__i386__) || defined(__x86_64__) 23 # define UNALIGNED_MEMOPS_ARE_FAST 1 24 #else 25 # define UNALIGNED_MEMOPS_ARE_FAST 0 26 #endif 27 28 #define N_WORDS (AES_BLOCK_SIZE / sizeof(unsigned long)) 29 typedef struct { 30 unsigned long data[N_WORDS]; 31 #if defined(__GNUC__) && UNALIGNED_MEMOPS_ARE_FAST 32 } aes_block_t __attribute((__aligned__(1))); 33 #else 34 } aes_block_t; 35 #endif 36 37 #if UNALIGNED_MEMOPS_ARE_FAST 38 # define load_block(d, s) (d) = *(const aes_block_t *)(s) 39 # define store_block(d, s) *(aes_block_t *)(d) = (s) 40 #else 41 # define load_block(d, s) memcpy((d).data, (s), AES_BLOCK_SIZE) 42 # define store_block(d, s) memcpy((d), (s).data, AES_BLOCK_SIZE) 43 #endif 44 45 /* N.B. The IV for this mode is _twice_ the block size */ 46 47 /* Use of this function is deprecated. */ 48 void AES_ige_encrypt(const unsigned char *in, unsigned char *out, 49 size_t length, const AES_KEY *key, 50 unsigned char *ivec, const int enc) 51 { 52 size_t n; 53 size_t len = length / AES_BLOCK_SIZE; 54 55 if (length == 0) 56 return; 57 58 OPENSSL_assert(in && out && key && ivec); 59 OPENSSL_assert((AES_ENCRYPT == enc) || (AES_DECRYPT == enc)); 60 OPENSSL_assert((length % AES_BLOCK_SIZE) == 0); 61 62 if (AES_ENCRYPT == enc) { 63 if (in != out && 64 (UNALIGNED_MEMOPS_ARE_FAST 65 || ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(long) == 66 0)) { 67 aes_block_t *ivp = (aes_block_t *) ivec; 68 aes_block_t *iv2p = (aes_block_t *) (ivec + AES_BLOCK_SIZE); 69 70 while (len) { 71 aes_block_t *inp = (aes_block_t *) in; 72 aes_block_t *outp = (aes_block_t *) out; 73 74 for (n = 0; n < N_WORDS; ++n) 75 outp->data[n] = inp->data[n] ^ ivp->data[n]; 76 AES_encrypt((unsigned char *)outp->data, 77 (unsigned char *)outp->data, key); 78 for (n = 0; n < N_WORDS; ++n) 79 outp->data[n] ^= iv2p->data[n]; 80 ivp = outp; 81 iv2p = inp; 82 --len; 83 in += AES_BLOCK_SIZE; 84 out += AES_BLOCK_SIZE; 85 } 86 memcpy(ivec, ivp->data, AES_BLOCK_SIZE); 87 memcpy(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE); 88 } else { 89 aes_block_t tmp, tmp2; 90 aes_block_t iv; 91 aes_block_t iv2; 92 93 load_block(iv, ivec); 94 load_block(iv2, ivec + AES_BLOCK_SIZE); 95 96 while (len) { 97 load_block(tmp, in); 98 for (n = 0; n < N_WORDS; ++n) 99 tmp2.data[n] = tmp.data[n] ^ iv.data[n]; 100 AES_encrypt((unsigned char *)tmp2.data, 101 (unsigned char *)tmp2.data, key); 102 for (n = 0; n < N_WORDS; ++n) 103 tmp2.data[n] ^= iv2.data[n]; 104 store_block(out, tmp2); 105 iv = tmp2; 106 iv2 = tmp; 107 --len; 108 in += AES_BLOCK_SIZE; 109 out += AES_BLOCK_SIZE; 110 } 111 memcpy(ivec, iv.data, AES_BLOCK_SIZE); 112 memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE); 113 } 114 } else { 115 if (in != out && 116 (UNALIGNED_MEMOPS_ARE_FAST 117 || ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(long) == 118 0)) { 119 aes_block_t *ivp = (aes_block_t *) ivec; 120 aes_block_t *iv2p = (aes_block_t *) (ivec + AES_BLOCK_SIZE); 121 122 while (len) { 123 aes_block_t tmp; 124 aes_block_t *inp = (aes_block_t *) in; 125 aes_block_t *outp = (aes_block_t *) out; 126 127 for (n = 0; n < N_WORDS; ++n) 128 tmp.data[n] = inp->data[n] ^ iv2p->data[n]; 129 AES_decrypt((unsigned char *)tmp.data, 130 (unsigned char *)outp->data, key); 131 for (n = 0; n < N_WORDS; ++n) 132 outp->data[n] ^= ivp->data[n]; 133 ivp = inp; 134 iv2p = outp; 135 --len; 136 in += AES_BLOCK_SIZE; 137 out += AES_BLOCK_SIZE; 138 } 139 memcpy(ivec, ivp->data, AES_BLOCK_SIZE); 140 memcpy(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE); 141 } else { 142 aes_block_t tmp, tmp2; 143 aes_block_t iv; 144 aes_block_t iv2; 145 146 load_block(iv, ivec); 147 load_block(iv2, ivec + AES_BLOCK_SIZE); 148 149 while (len) { 150 load_block(tmp, in); 151 tmp2 = tmp; 152 for (n = 0; n < N_WORDS; ++n) 153 tmp.data[n] ^= iv2.data[n]; 154 AES_decrypt((unsigned char *)tmp.data, 155 (unsigned char *)tmp.data, key); 156 for (n = 0; n < N_WORDS; ++n) 157 tmp.data[n] ^= iv.data[n]; 158 store_block(out, tmp); 159 iv = tmp2; 160 iv2 = tmp; 161 --len; 162 in += AES_BLOCK_SIZE; 163 out += AES_BLOCK_SIZE; 164 } 165 memcpy(ivec, iv.data, AES_BLOCK_SIZE); 166 memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE); 167 } 168 } 169 } 170 171 /* 172 * Note that its effectively impossible to do biIGE in anything other 173 * than a single pass, so no provision is made for chaining. 174 * 175 * NB: The implementation of AES_bi_ige_encrypt has a bug. It is supposed to use 176 * 2 AES keys, but in fact only one is ever used. This bug has been present 177 * since this code was first implemented. It is believed to have minimal 178 * security impact in practice and has therefore not been fixed for backwards 179 * compatibility reasons. 180 * 181 * Use of this function is deprecated. 182 */ 183 184 /* N.B. The IV for this mode is _four times_ the block size */ 185 186 void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out, 187 size_t length, const AES_KEY *key, 188 const AES_KEY *key2, const unsigned char *ivec, 189 const int enc) 190 { 191 size_t n; 192 size_t len = length; 193 unsigned char tmp[AES_BLOCK_SIZE]; 194 unsigned char tmp2[AES_BLOCK_SIZE]; 195 unsigned char tmp3[AES_BLOCK_SIZE]; 196 unsigned char prev[AES_BLOCK_SIZE]; 197 const unsigned char *iv; 198 const unsigned char *iv2; 199 200 OPENSSL_assert(in && out && key && ivec); 201 OPENSSL_assert((AES_ENCRYPT == enc) || (AES_DECRYPT == enc)); 202 OPENSSL_assert((length % AES_BLOCK_SIZE) == 0); 203 204 if (AES_ENCRYPT == enc) { 205 /* 206 * XXX: Do a separate case for when in != out (strictly should check 207 * for overlap, too) 208 */ 209 210 /* First the forward pass */ 211 iv = ivec; 212 iv2 = ivec + AES_BLOCK_SIZE; 213 while (len >= AES_BLOCK_SIZE) { 214 for (n = 0; n < AES_BLOCK_SIZE; ++n) 215 out[n] = in[n] ^ iv[n]; 216 AES_encrypt(out, out, key); 217 for (n = 0; n < AES_BLOCK_SIZE; ++n) 218 out[n] ^= iv2[n]; 219 iv = out; 220 memcpy(prev, in, AES_BLOCK_SIZE); 221 iv2 = prev; 222 len -= AES_BLOCK_SIZE; 223 in += AES_BLOCK_SIZE; 224 out += AES_BLOCK_SIZE; 225 } 226 227 /* And now backwards */ 228 iv = ivec + AES_BLOCK_SIZE * 2; 229 iv2 = ivec + AES_BLOCK_SIZE * 3; 230 len = length; 231 while (len >= AES_BLOCK_SIZE) { 232 out -= AES_BLOCK_SIZE; 233 /* 234 * XXX: reduce copies by alternating between buffers 235 */ 236 memcpy(tmp, out, AES_BLOCK_SIZE); 237 for (n = 0; n < AES_BLOCK_SIZE; ++n) 238 out[n] ^= iv[n]; 239 /* 240 * hexdump(stdout, "out ^ iv", out, AES_BLOCK_SIZE); 241 */ 242 AES_encrypt(out, out, key); 243 /* 244 * hexdump(stdout,"enc", out, AES_BLOCK_SIZE); 245 */ 246 /* 247 * hexdump(stdout,"iv2", iv2, AES_BLOCK_SIZE); 248 */ 249 for (n = 0; n < AES_BLOCK_SIZE; ++n) 250 out[n] ^= iv2[n]; 251 /* 252 * hexdump(stdout,"out", out, AES_BLOCK_SIZE); 253 */ 254 iv = out; 255 memcpy(prev, tmp, AES_BLOCK_SIZE); 256 iv2 = prev; 257 len -= AES_BLOCK_SIZE; 258 } 259 } else { 260 /* First backwards */ 261 iv = ivec + AES_BLOCK_SIZE * 2; 262 iv2 = ivec + AES_BLOCK_SIZE * 3; 263 in += length; 264 out += length; 265 while (len >= AES_BLOCK_SIZE) { 266 in -= AES_BLOCK_SIZE; 267 out -= AES_BLOCK_SIZE; 268 memcpy(tmp, in, AES_BLOCK_SIZE); 269 memcpy(tmp2, in, AES_BLOCK_SIZE); 270 for (n = 0; n < AES_BLOCK_SIZE; ++n) 271 tmp[n] ^= iv2[n]; 272 AES_decrypt(tmp, out, key); 273 for (n = 0; n < AES_BLOCK_SIZE; ++n) 274 out[n] ^= iv[n]; 275 memcpy(tmp3, tmp2, AES_BLOCK_SIZE); 276 iv = tmp3; 277 iv2 = out; 278 len -= AES_BLOCK_SIZE; 279 } 280 281 /* And now forwards */ 282 iv = ivec; 283 iv2 = ivec + AES_BLOCK_SIZE; 284 len = length; 285 while (len >= AES_BLOCK_SIZE) { 286 memcpy(tmp, out, AES_BLOCK_SIZE); 287 memcpy(tmp2, out, AES_BLOCK_SIZE); 288 for (n = 0; n < AES_BLOCK_SIZE; ++n) 289 tmp[n] ^= iv2[n]; 290 AES_decrypt(tmp, out, key); 291 for (n = 0; n < AES_BLOCK_SIZE; ++n) 292 out[n] ^= iv[n]; 293 memcpy(tmp3, tmp2, AES_BLOCK_SIZE); 294 iv = tmp3; 295 iv2 = out; 296 len -= AES_BLOCK_SIZE; 297 in += AES_BLOCK_SIZE; 298 out += AES_BLOCK_SIZE; 299 } 300 } 301 } 302