1ed5d4f9aSSimon L. B. Nielsen /* crypto/aes/aes_ige.c -*- mode:C; c-file-style: "eay" -*- */ 2ed5d4f9aSSimon L. B. Nielsen /* ==================================================================== 3ed5d4f9aSSimon L. B. Nielsen * Copyright (c) 2006 The OpenSSL Project. All rights reserved. 4ed5d4f9aSSimon L. B. Nielsen * 5ed5d4f9aSSimon L. B. Nielsen * Redistribution and use in source and binary forms, with or without 6ed5d4f9aSSimon L. B. Nielsen * modification, are permitted provided that the following conditions 7ed5d4f9aSSimon L. B. Nielsen * are met: 8ed5d4f9aSSimon L. B. Nielsen * 9ed5d4f9aSSimon L. B. Nielsen * 1. Redistributions of source code must retain the above copyright 10ed5d4f9aSSimon L. B. Nielsen * notice, this list of conditions and the following disclaimer. 11ed5d4f9aSSimon L. B. Nielsen * 12ed5d4f9aSSimon L. B. Nielsen * 2. Redistributions in binary form must reproduce the above copyright 13ed5d4f9aSSimon L. B. Nielsen * notice, this list of conditions and the following disclaimer in 14ed5d4f9aSSimon L. B. Nielsen * the documentation and/or other materials provided with the 15ed5d4f9aSSimon L. B. Nielsen * distribution. 16ed5d4f9aSSimon L. B. Nielsen * 17ed5d4f9aSSimon L. B. Nielsen * 3. All advertising materials mentioning features or use of this 18ed5d4f9aSSimon L. B. Nielsen * software must display the following acknowledgment: 19ed5d4f9aSSimon L. B. Nielsen * "This product includes software developed by the OpenSSL Project 20ed5d4f9aSSimon L. B. Nielsen * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 21ed5d4f9aSSimon L. B. Nielsen * 22ed5d4f9aSSimon L. B. Nielsen * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 23ed5d4f9aSSimon L. B. Nielsen * endorse or promote products derived from this software without 24ed5d4f9aSSimon L. B. Nielsen * prior written permission. For written permission, please contact 25ed5d4f9aSSimon L. B. Nielsen * openssl-core@openssl.org. 26ed5d4f9aSSimon L. B. Nielsen * 27ed5d4f9aSSimon L. B. Nielsen * 5. Products derived from this software may not be called "OpenSSL" 28ed5d4f9aSSimon L. B. Nielsen * nor may "OpenSSL" appear in their names without prior written 29ed5d4f9aSSimon L. B. Nielsen * permission of the OpenSSL Project. 30ed5d4f9aSSimon L. B. Nielsen * 31ed5d4f9aSSimon L. B. Nielsen * 6. Redistributions of any form whatsoever must retain the following 32ed5d4f9aSSimon L. B. Nielsen * acknowledgment: 33ed5d4f9aSSimon L. B. Nielsen * "This product includes software developed by the OpenSSL Project 34ed5d4f9aSSimon L. B. Nielsen * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 35ed5d4f9aSSimon L. B. Nielsen * 36ed5d4f9aSSimon L. B. Nielsen * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 37ed5d4f9aSSimon L. B. Nielsen * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 38ed5d4f9aSSimon L. B. Nielsen * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 39ed5d4f9aSSimon L. B. Nielsen * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 40ed5d4f9aSSimon L. B. Nielsen * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 41ed5d4f9aSSimon L. B. Nielsen * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 42ed5d4f9aSSimon L. B. Nielsen * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 43ed5d4f9aSSimon L. B. Nielsen * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 44ed5d4f9aSSimon L. B. Nielsen * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 45ed5d4f9aSSimon L. B. Nielsen * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 46ed5d4f9aSSimon L. B. Nielsen * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 47ed5d4f9aSSimon L. B. Nielsen * OF THE POSSIBILITY OF SUCH DAMAGE. 48ed5d4f9aSSimon L. B. Nielsen * ==================================================================== 49ed5d4f9aSSimon L. B. Nielsen * 50ed5d4f9aSSimon L. B. Nielsen */ 51ed5d4f9aSSimon L. B. Nielsen 52ed5d4f9aSSimon L. B. Nielsen #include "cryptlib.h" 53ed5d4f9aSSimon L. B. Nielsen 54ed5d4f9aSSimon L. B. Nielsen #include <openssl/aes.h> 55ed5d4f9aSSimon L. B. Nielsen #include "aes_locl.h" 56ed5d4f9aSSimon L. B. Nielsen 57ed5d4f9aSSimon L. B. Nielsen /* 58ed5d4f9aSSimon L. B. Nielsen static void hexdump(FILE *f,const char *title,const unsigned char *s,int l) 59ed5d4f9aSSimon L. B. Nielsen { 60ed5d4f9aSSimon L. B. Nielsen int n=0; 61ed5d4f9aSSimon L. B. Nielsen 62ed5d4f9aSSimon L. B. Nielsen fprintf(f,"%s",title); 63ed5d4f9aSSimon L. B. Nielsen for( ; n < l ; ++n) 64ed5d4f9aSSimon L. B. Nielsen { 65ed5d4f9aSSimon L. B. Nielsen if((n%16) == 0) 66ed5d4f9aSSimon L. B. Nielsen fprintf(f,"\n%04x",n); 67ed5d4f9aSSimon L. B. Nielsen fprintf(f," %02x",s[n]); 68ed5d4f9aSSimon L. B. Nielsen } 69ed5d4f9aSSimon L. B. Nielsen fprintf(f,"\n"); 70ed5d4f9aSSimon L. B. Nielsen } 71ed5d4f9aSSimon L. B. Nielsen */ 72ed5d4f9aSSimon L. B. Nielsen 73ed5d4f9aSSimon L. B. Nielsen /* N.B. The IV for this mode is _twice_ the block size */ 74ed5d4f9aSSimon L. B. Nielsen 75ed5d4f9aSSimon L. B. Nielsen void AES_ige_encrypt(const unsigned char *in, unsigned char *out, 76ed5d4f9aSSimon L. B. Nielsen const unsigned long length, const AES_KEY *key, 77ed5d4f9aSSimon L. B. Nielsen unsigned char *ivec, const int enc) 78ed5d4f9aSSimon L. B. Nielsen { 79ed5d4f9aSSimon L. B. Nielsen unsigned long n; 80ed5d4f9aSSimon L. B. Nielsen unsigned long len = length; 81ed5d4f9aSSimon L. B. Nielsen unsigned char tmp[AES_BLOCK_SIZE]; 82ed5d4f9aSSimon L. B. Nielsen unsigned char tmp2[AES_BLOCK_SIZE]; 83ed5d4f9aSSimon L. B. Nielsen unsigned char prev[AES_BLOCK_SIZE]; 84ed5d4f9aSSimon L. B. Nielsen const unsigned char *iv = ivec; 85ed5d4f9aSSimon L. B. Nielsen const unsigned char *iv2 = ivec + AES_BLOCK_SIZE; 86ed5d4f9aSSimon L. B. Nielsen 87ed5d4f9aSSimon L. B. Nielsen OPENSSL_assert(in && out && key && ivec); 88ed5d4f9aSSimon L. B. Nielsen OPENSSL_assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc)); 89ed5d4f9aSSimon L. B. Nielsen OPENSSL_assert((length%AES_BLOCK_SIZE) == 0); 90ed5d4f9aSSimon L. B. Nielsen 91ed5d4f9aSSimon L. B. Nielsen if (AES_ENCRYPT == enc) 92ed5d4f9aSSimon L. B. Nielsen { 93ed5d4f9aSSimon L. B. Nielsen /* XXX: Do a separate case for when in != out (strictly should 94ed5d4f9aSSimon L. B. Nielsen check for overlap, too) */ 95ed5d4f9aSSimon L. B. Nielsen while (len >= AES_BLOCK_SIZE) 96ed5d4f9aSSimon L. B. Nielsen { 97ed5d4f9aSSimon L. B. Nielsen /* hexdump(stdout, "in", in, AES_BLOCK_SIZE); */ 98ed5d4f9aSSimon L. B. Nielsen /* hexdump(stdout, "iv", iv, AES_BLOCK_SIZE); */ 99ed5d4f9aSSimon L. B. Nielsen for(n=0 ; n < AES_BLOCK_SIZE ; ++n) 100ed5d4f9aSSimon L. B. Nielsen out[n] = in[n] ^ iv[n]; 101ed5d4f9aSSimon L. B. Nielsen /* hexdump(stdout, "in ^ iv", out, AES_BLOCK_SIZE); */ 102ed5d4f9aSSimon L. B. Nielsen AES_encrypt(out, out, key); 103ed5d4f9aSSimon L. B. Nielsen /* hexdump(stdout,"enc", out, AES_BLOCK_SIZE); */ 104ed5d4f9aSSimon L. B. Nielsen /* hexdump(stdout,"iv2", iv2, AES_BLOCK_SIZE); */ 105ed5d4f9aSSimon L. B. Nielsen for(n=0 ; n < AES_BLOCK_SIZE ; ++n) 106ed5d4f9aSSimon L. B. Nielsen out[n] ^= iv2[n]; 107ed5d4f9aSSimon L. B. Nielsen /* hexdump(stdout,"out", out, AES_BLOCK_SIZE); */ 108ed5d4f9aSSimon L. B. Nielsen iv = out; 109ed5d4f9aSSimon L. B. Nielsen memcpy(prev, in, AES_BLOCK_SIZE); 110ed5d4f9aSSimon L. B. Nielsen iv2 = prev; 111ed5d4f9aSSimon L. B. Nielsen len -= AES_BLOCK_SIZE; 112ed5d4f9aSSimon L. B. Nielsen in += AES_BLOCK_SIZE; 113ed5d4f9aSSimon L. B. Nielsen out += AES_BLOCK_SIZE; 114ed5d4f9aSSimon L. B. Nielsen } 115ed5d4f9aSSimon L. B. Nielsen memcpy(ivec, iv, AES_BLOCK_SIZE); 116ed5d4f9aSSimon L. B. Nielsen memcpy(ivec + AES_BLOCK_SIZE, iv2, AES_BLOCK_SIZE); 117ed5d4f9aSSimon L. B. Nielsen } 118ed5d4f9aSSimon L. B. Nielsen else 119ed5d4f9aSSimon L. B. Nielsen { 120ed5d4f9aSSimon L. B. Nielsen while (len >= AES_BLOCK_SIZE) 121ed5d4f9aSSimon L. B. Nielsen { 122ed5d4f9aSSimon L. B. Nielsen memcpy(tmp, in, AES_BLOCK_SIZE); 123ed5d4f9aSSimon L. B. Nielsen memcpy(tmp2, in, AES_BLOCK_SIZE); 124ed5d4f9aSSimon L. B. Nielsen /* hexdump(stdout, "in", in, AES_BLOCK_SIZE); */ 125ed5d4f9aSSimon L. B. Nielsen /* hexdump(stdout, "iv2", iv2, AES_BLOCK_SIZE); */ 126ed5d4f9aSSimon L. B. Nielsen for(n=0 ; n < AES_BLOCK_SIZE ; ++n) 127ed5d4f9aSSimon L. B. Nielsen tmp[n] ^= iv2[n]; 128ed5d4f9aSSimon L. B. Nielsen /* hexdump(stdout, "in ^ iv2", tmp, AES_BLOCK_SIZE); */ 129ed5d4f9aSSimon L. B. Nielsen AES_decrypt(tmp, out, key); 130ed5d4f9aSSimon L. B. Nielsen /* hexdump(stdout, "dec", out, AES_BLOCK_SIZE); */ 131ed5d4f9aSSimon L. B. Nielsen /* hexdump(stdout, "iv", ivec, AES_BLOCK_SIZE); */ 132ed5d4f9aSSimon L. B. Nielsen for(n=0 ; n < AES_BLOCK_SIZE ; ++n) 133ed5d4f9aSSimon L. B. Nielsen out[n] ^= ivec[n]; 134ed5d4f9aSSimon L. B. Nielsen /* hexdump(stdout, "out", out, AES_BLOCK_SIZE); */ 135ed5d4f9aSSimon L. B. Nielsen memcpy(ivec, tmp2, AES_BLOCK_SIZE); 136ed5d4f9aSSimon L. B. Nielsen iv2 = out; 137ed5d4f9aSSimon L. B. Nielsen len -= AES_BLOCK_SIZE; 138ed5d4f9aSSimon L. B. Nielsen in += AES_BLOCK_SIZE; 139ed5d4f9aSSimon L. B. Nielsen out += AES_BLOCK_SIZE; 140ed5d4f9aSSimon L. B. Nielsen } 141ed5d4f9aSSimon L. B. Nielsen memcpy(ivec + AES_BLOCK_SIZE, iv2, AES_BLOCK_SIZE); 142ed5d4f9aSSimon L. B. Nielsen } 143ed5d4f9aSSimon L. B. Nielsen } 144ed5d4f9aSSimon L. B. Nielsen 145ed5d4f9aSSimon L. B. Nielsen /* 146ed5d4f9aSSimon L. B. Nielsen * Note that its effectively impossible to do biIGE in anything other 147ed5d4f9aSSimon L. B. Nielsen * than a single pass, so no provision is made for chaining. 148ed5d4f9aSSimon L. B. Nielsen */ 149ed5d4f9aSSimon L. B. Nielsen 150ed5d4f9aSSimon L. B. Nielsen /* N.B. The IV for this mode is _four times_ the block size */ 151ed5d4f9aSSimon L. B. Nielsen 152ed5d4f9aSSimon L. B. Nielsen void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out, 153ed5d4f9aSSimon L. B. Nielsen const unsigned long length, const AES_KEY *key, 154ed5d4f9aSSimon L. B. Nielsen const AES_KEY *key2, const unsigned char *ivec, 155ed5d4f9aSSimon L. B. Nielsen const int enc) 156ed5d4f9aSSimon L. B. Nielsen { 157ed5d4f9aSSimon L. B. Nielsen unsigned long n; 158ed5d4f9aSSimon L. B. Nielsen unsigned long len = length; 159ed5d4f9aSSimon L. B. Nielsen unsigned char tmp[AES_BLOCK_SIZE]; 160ed5d4f9aSSimon L. B. Nielsen unsigned char tmp2[AES_BLOCK_SIZE]; 161ed5d4f9aSSimon L. B. Nielsen unsigned char tmp3[AES_BLOCK_SIZE]; 162ed5d4f9aSSimon L. B. Nielsen unsigned char prev[AES_BLOCK_SIZE]; 163ed5d4f9aSSimon L. B. Nielsen const unsigned char *iv; 164ed5d4f9aSSimon L. B. Nielsen const unsigned char *iv2; 165ed5d4f9aSSimon L. B. Nielsen 166ed5d4f9aSSimon L. B. Nielsen OPENSSL_assert(in && out && key && ivec); 167ed5d4f9aSSimon L. B. Nielsen OPENSSL_assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc)); 168ed5d4f9aSSimon L. B. Nielsen OPENSSL_assert((length%AES_BLOCK_SIZE) == 0); 169ed5d4f9aSSimon L. B. Nielsen 170ed5d4f9aSSimon L. B. Nielsen if (AES_ENCRYPT == enc) 171ed5d4f9aSSimon L. B. Nielsen { 172ed5d4f9aSSimon L. B. Nielsen /* XXX: Do a separate case for when in != out (strictly should 173ed5d4f9aSSimon L. B. Nielsen check for overlap, too) */ 174ed5d4f9aSSimon L. B. Nielsen 175ed5d4f9aSSimon L. B. Nielsen /* First the forward pass */ 176ed5d4f9aSSimon L. B. Nielsen iv = ivec; 177ed5d4f9aSSimon L. B. Nielsen iv2 = ivec + AES_BLOCK_SIZE; 178ed5d4f9aSSimon L. B. Nielsen while (len >= AES_BLOCK_SIZE) 179ed5d4f9aSSimon L. B. Nielsen { 180ed5d4f9aSSimon L. B. Nielsen /* hexdump(stdout, "in", in, AES_BLOCK_SIZE); */ 181ed5d4f9aSSimon L. B. Nielsen /* hexdump(stdout, "iv", iv, AES_BLOCK_SIZE); */ 182ed5d4f9aSSimon L. B. Nielsen for(n=0 ; n < AES_BLOCK_SIZE ; ++n) 183ed5d4f9aSSimon L. B. Nielsen out[n] = in[n] ^ iv[n]; 184ed5d4f9aSSimon L. B. Nielsen /* hexdump(stdout, "in ^ iv", out, AES_BLOCK_SIZE); */ 185ed5d4f9aSSimon L. B. Nielsen AES_encrypt(out, out, key); 186ed5d4f9aSSimon L. B. Nielsen /* hexdump(stdout,"enc", out, AES_BLOCK_SIZE); */ 187ed5d4f9aSSimon L. B. Nielsen /* hexdump(stdout,"iv2", iv2, AES_BLOCK_SIZE); */ 188ed5d4f9aSSimon L. B. Nielsen for(n=0 ; n < AES_BLOCK_SIZE ; ++n) 189ed5d4f9aSSimon L. B. Nielsen out[n] ^= iv2[n]; 190ed5d4f9aSSimon L. B. Nielsen /* hexdump(stdout,"out", out, AES_BLOCK_SIZE); */ 191ed5d4f9aSSimon L. B. Nielsen iv = out; 192ed5d4f9aSSimon L. B. Nielsen memcpy(prev, in, AES_BLOCK_SIZE); 193ed5d4f9aSSimon L. B. Nielsen iv2 = prev; 194ed5d4f9aSSimon L. B. Nielsen len -= AES_BLOCK_SIZE; 195ed5d4f9aSSimon L. B. Nielsen in += AES_BLOCK_SIZE; 196ed5d4f9aSSimon L. B. Nielsen out += AES_BLOCK_SIZE; 197ed5d4f9aSSimon L. B. Nielsen } 198ed5d4f9aSSimon L. B. Nielsen 199ed5d4f9aSSimon L. B. Nielsen /* And now backwards */ 200ed5d4f9aSSimon L. B. Nielsen iv = ivec + AES_BLOCK_SIZE*2; 201ed5d4f9aSSimon L. B. Nielsen iv2 = ivec + AES_BLOCK_SIZE*3; 202ed5d4f9aSSimon L. B. Nielsen len = length; 203ed5d4f9aSSimon L. B. Nielsen while(len >= AES_BLOCK_SIZE) 204ed5d4f9aSSimon L. B. Nielsen { 205ed5d4f9aSSimon L. B. Nielsen out -= AES_BLOCK_SIZE; 206ed5d4f9aSSimon L. B. Nielsen /* hexdump(stdout, "intermediate", out, AES_BLOCK_SIZE); */ 207ed5d4f9aSSimon L. B. Nielsen /* hexdump(stdout, "iv", iv, AES_BLOCK_SIZE); */ 208ed5d4f9aSSimon L. B. Nielsen /* XXX: reduce copies by alternating between buffers */ 209ed5d4f9aSSimon L. B. Nielsen memcpy(tmp, out, AES_BLOCK_SIZE); 210ed5d4f9aSSimon L. B. Nielsen for(n=0 ; n < AES_BLOCK_SIZE ; ++n) 211ed5d4f9aSSimon L. B. Nielsen out[n] ^= iv[n]; 212ed5d4f9aSSimon L. B. Nielsen /* hexdump(stdout, "out ^ iv", out, AES_BLOCK_SIZE); */ 213ed5d4f9aSSimon L. B. Nielsen AES_encrypt(out, out, key); 214ed5d4f9aSSimon L. B. Nielsen /* hexdump(stdout,"enc", out, AES_BLOCK_SIZE); */ 215ed5d4f9aSSimon L. B. Nielsen /* hexdump(stdout,"iv2", iv2, AES_BLOCK_SIZE); */ 216ed5d4f9aSSimon L. B. Nielsen for(n=0 ; n < AES_BLOCK_SIZE ; ++n) 217ed5d4f9aSSimon L. B. Nielsen out[n] ^= iv2[n]; 218ed5d4f9aSSimon L. B. Nielsen /* hexdump(stdout,"out", out, AES_BLOCK_SIZE); */ 219ed5d4f9aSSimon L. B. Nielsen iv = out; 220ed5d4f9aSSimon L. B. Nielsen memcpy(prev, tmp, AES_BLOCK_SIZE); 221ed5d4f9aSSimon L. B. Nielsen iv2 = prev; 222ed5d4f9aSSimon L. B. Nielsen len -= AES_BLOCK_SIZE; 223ed5d4f9aSSimon L. B. Nielsen } 224ed5d4f9aSSimon L. B. Nielsen } 225ed5d4f9aSSimon L. B. Nielsen else 226ed5d4f9aSSimon L. B. Nielsen { 227ed5d4f9aSSimon L. B. Nielsen /* First backwards */ 228ed5d4f9aSSimon L. B. Nielsen iv = ivec + AES_BLOCK_SIZE*2; 229ed5d4f9aSSimon L. B. Nielsen iv2 = ivec + AES_BLOCK_SIZE*3; 230ed5d4f9aSSimon L. B. Nielsen in += length; 231ed5d4f9aSSimon L. B. Nielsen out += length; 232ed5d4f9aSSimon L. B. Nielsen while (len >= AES_BLOCK_SIZE) 233ed5d4f9aSSimon L. B. Nielsen { 234ed5d4f9aSSimon L. B. Nielsen in -= AES_BLOCK_SIZE; 235ed5d4f9aSSimon L. B. Nielsen out -= AES_BLOCK_SIZE; 236ed5d4f9aSSimon L. B. Nielsen memcpy(tmp, in, AES_BLOCK_SIZE); 237ed5d4f9aSSimon L. B. Nielsen memcpy(tmp2, in, AES_BLOCK_SIZE); 238ed5d4f9aSSimon L. B. Nielsen /* hexdump(stdout, "in", in, AES_BLOCK_SIZE); */ 239ed5d4f9aSSimon L. B. Nielsen /* hexdump(stdout, "iv2", iv2, AES_BLOCK_SIZE); */ 240ed5d4f9aSSimon L. B. Nielsen for(n=0 ; n < AES_BLOCK_SIZE ; ++n) 241ed5d4f9aSSimon L. B. Nielsen tmp[n] ^= iv2[n]; 242ed5d4f9aSSimon L. B. Nielsen /* hexdump(stdout, "in ^ iv2", tmp, AES_BLOCK_SIZE); */ 243ed5d4f9aSSimon L. B. Nielsen AES_decrypt(tmp, out, key); 244ed5d4f9aSSimon L. B. Nielsen /* hexdump(stdout, "dec", out, AES_BLOCK_SIZE); */ 245ed5d4f9aSSimon L. B. Nielsen /* hexdump(stdout, "iv", iv, AES_BLOCK_SIZE); */ 246ed5d4f9aSSimon L. B. Nielsen for(n=0 ; n < AES_BLOCK_SIZE ; ++n) 247ed5d4f9aSSimon L. B. Nielsen out[n] ^= iv[n]; 248ed5d4f9aSSimon L. B. Nielsen /* hexdump(stdout, "out", out, AES_BLOCK_SIZE); */ 249ed5d4f9aSSimon L. B. Nielsen memcpy(tmp3, tmp2, AES_BLOCK_SIZE); 250ed5d4f9aSSimon L. B. Nielsen iv = tmp3; 251ed5d4f9aSSimon L. B. Nielsen iv2 = out; 252ed5d4f9aSSimon L. B. Nielsen len -= AES_BLOCK_SIZE; 253ed5d4f9aSSimon L. B. Nielsen } 254ed5d4f9aSSimon L. B. Nielsen 255ed5d4f9aSSimon L. B. Nielsen /* And now forwards */ 256ed5d4f9aSSimon L. B. Nielsen iv = ivec; 257ed5d4f9aSSimon L. B. Nielsen iv2 = ivec + AES_BLOCK_SIZE; 258ed5d4f9aSSimon L. B. Nielsen len = length; 259ed5d4f9aSSimon L. B. Nielsen while (len >= AES_BLOCK_SIZE) 260ed5d4f9aSSimon L. B. Nielsen { 261ed5d4f9aSSimon L. B. Nielsen memcpy(tmp, out, AES_BLOCK_SIZE); 262ed5d4f9aSSimon L. B. Nielsen memcpy(tmp2, out, AES_BLOCK_SIZE); 263ed5d4f9aSSimon L. B. Nielsen /* hexdump(stdout, "intermediate", out, AES_BLOCK_SIZE); */ 264ed5d4f9aSSimon L. B. Nielsen /* hexdump(stdout, "iv2", iv2, AES_BLOCK_SIZE); */ 265ed5d4f9aSSimon L. B. Nielsen for(n=0 ; n < AES_BLOCK_SIZE ; ++n) 266ed5d4f9aSSimon L. B. Nielsen tmp[n] ^= iv2[n]; 267ed5d4f9aSSimon L. B. Nielsen /* hexdump(stdout, "out ^ iv2", tmp, AES_BLOCK_SIZE); */ 268ed5d4f9aSSimon L. B. Nielsen AES_decrypt(tmp, out, key); 269ed5d4f9aSSimon L. B. Nielsen /* hexdump(stdout, "dec", out, AES_BLOCK_SIZE); */ 270ed5d4f9aSSimon L. B. Nielsen /* hexdump(stdout, "iv", ivec, AES_BLOCK_SIZE); */ 271ed5d4f9aSSimon L. B. Nielsen for(n=0 ; n < AES_BLOCK_SIZE ; ++n) 272ed5d4f9aSSimon L. B. Nielsen out[n] ^= iv[n]; 273ed5d4f9aSSimon L. B. Nielsen /* hexdump(stdout, "out", out, AES_BLOCK_SIZE); */ 274ed5d4f9aSSimon L. B. Nielsen memcpy(tmp3, tmp2, AES_BLOCK_SIZE); 275ed5d4f9aSSimon L. B. Nielsen iv = tmp3; 276ed5d4f9aSSimon L. B. Nielsen iv2 = out; 277ed5d4f9aSSimon L. B. Nielsen len -= AES_BLOCK_SIZE; 278ed5d4f9aSSimon L. B. Nielsen in += AES_BLOCK_SIZE; 279ed5d4f9aSSimon L. B. Nielsen out += AES_BLOCK_SIZE; 280ed5d4f9aSSimon L. B. Nielsen } 281ed5d4f9aSSimon L. B. Nielsen 282ed5d4f9aSSimon L. B. Nielsen } 283ed5d4f9aSSimon L. B. Nielsen } 284