11558Srgrimes/* ==================================================================== 21558Srgrimes * Copyright (c) 2008 The OpenSSL Project. All rights reserved. 31558Srgrimes * 41558Srgrimes * Redistribution and use in source and binary forms, with or without 51558Srgrimes * modification, are permitted provided that the following conditions 61558Srgrimes * are met: 71558Srgrimes * 81558Srgrimes * 1. Redistributions of source code must retain the above copyright 91558Srgrimes * notice, this list of conditions and the following disclaimer. 101558Srgrimes * 111558Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 121558Srgrimes * notice, this list of conditions and the following disclaimer in 131558Srgrimes * the documentation and/or other materials provided with the 141558Srgrimes * distribution. 151558Srgrimes * 161558Srgrimes * 3. All advertising materials mentioning features or use of this 171558Srgrimes * software must display the following acknowledgment: 181558Srgrimes * "This product includes software developed by the OpenSSL Project 191558Srgrimes * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 201558Srgrimes * 211558Srgrimes * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 221558Srgrimes * endorse or promote products derived from this software without 231558Srgrimes * prior written permission. For written permission, please contact 241558Srgrimes * openssl-core@openssl.org. 251558Srgrimes * 261558Srgrimes * 5. Products derived from this software may not be called "OpenSSL" 271558Srgrimes * nor may "OpenSSL" appear in their names without prior written 281558Srgrimes * permission of the OpenSSL Project. 291558Srgrimes * 301558Srgrimes * 6. Redistributions of any form whatsoever must retain the following 311558Srgrimes * acknowledgment: 321558Srgrimes * "This product includes software developed by the OpenSSL Project 331558Srgrimes * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 341558Srgrimes * 3537909Scharnier * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 361558Srgrimes * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 371558Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 381558Srgrimes * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 391558Srgrimes * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 401558Srgrimes * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 4137909Scharnier * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 421558Srgrimes * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4337909Scharnier * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 4437909Scharnier * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 4547095Sluoqi * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 461558Srgrimes * OF THE POSSIBILITY OF SUCH DAMAGE. 471558Srgrimes * ==================================================================== 481558Srgrimes * 491558Srgrimes */ 501558Srgrimes 511558Srgrimes#include <openssl/crypto.h> 5247095Sluoqi#include "modes_lcl.h" 531558Srgrimes#include <string.h> 541599Srgrimes 551618Srgrimes#ifndef MODES_DEBUG 5612806Speter# ifndef NDEBUG 571599Srgrimes# define NDEBUG 581558Srgrimes# endif 591558Srgrimes#endif 601558Srgrimes#include <assert.h> 611558Srgrimes 621558Srgrimes#ifndef STRICT_ALIGNMENT 631558Srgrimes# define STRICT_ALIGNMENT 0 641558Srgrimes#endif 651558Srgrimes 661558Srgrimesvoid CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out, 6717717Swosch size_t len, const void *key, 681558Srgrimes unsigned char ivec[16], block128_f block) 6944688Sgallatin{ 7044688Sgallatin size_t n; 7144688Sgallatin const unsigned char *iv = ivec; 7244688Sgallatin 7344688Sgallatin assert(in && out && key && ivec); 741558Srgrimes 7544688Sgallatin#if !defined(OPENSSL_SMALL_FOOTPRINT) 761558Srgrimes if (STRICT_ALIGNMENT && 771558Srgrimes ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) { 7847095Sluoqi while (len>=16) { 791558Srgrimes for(n=0; n<16; ++n) 8047095Sluoqi out[n] = in[n] ^ iv[n]; 8134963Sphk (*block)(out, out, key); 8247095Sluoqi iv = out; 831558Srgrimes len -= 16; 8447095Sluoqi in += 16; 851558Srgrimes out += 16; 8647095Sluoqi } 871558Srgrimes } else { 8847095Sluoqi while (len>=16) { 891558Srgrimes for(n=0; n<16; n+=sizeof(size_t)) 901558Srgrimes *(size_t*)(out+n) = 911558Srgrimes *(size_t*)(in+n) ^ *(size_t*)(iv+n); 9247095Sluoqi (*block)(out, out, key); 931558Srgrimes iv = out; 941558Srgrimes len -= 16; 951558Srgrimes in += 16; 9647095Sluoqi out += 16; 9747095Sluoqi } 981558Srgrimes } 991558Srgrimes#endif 1001558Srgrimes while (len) { 1011558Srgrimes for(n=0; n<16 && n<len; ++n) 1021558Srgrimes out[n] = in[n] ^ iv[n]; 1031558Srgrimes for(; n<16; ++n) 1041558Srgrimes out[n] = iv[n]; 1051558Srgrimes (*block)(out, out, key); 1061558Srgrimes iv = out; 1071558Srgrimes if (len<=16) break; 1081558Srgrimes len -= 16; 1091558Srgrimes in += 16; 1101856Sdg out += 16; 1111558Srgrimes } 1121558Srgrimes memcpy(ivec,iv,16); 1131558Srgrimes} 1141558Srgrimes 1151558Srgrimesvoid CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out, 1161558Srgrimes size_t len, const void *key, 1171558Srgrimes unsigned char ivec[16], block128_f block) 1181558Srgrimes{ 1191558Srgrimes size_t n; 1201558Srgrimes union { size_t t[16/sizeof(size_t)]; unsigned char c[16]; } tmp; 1211558Srgrimes 1221558Srgrimes assert(in && out && key && ivec); 1231558Srgrimes 1241558Srgrimes#if !defined(OPENSSL_SMALL_FOOTPRINT) 1251558Srgrimes if (in != out) { 1261558Srgrimes const unsigned char *iv = ivec; 1271558Srgrimes 1281558Srgrimes if (STRICT_ALIGNMENT && 12918916Sjoerg ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) { 1301558Srgrimes while (len>=16) { 1311558Srgrimes (*block)(in, out, key); 1321558Srgrimes for(n=0; n<16; ++n) 1333041Swollman out[n] ^= iv[n]; 1341558Srgrimes iv = in; 1351558Srgrimes len -= 16; 1361558Srgrimes in += 16; 1371558Srgrimes out += 16; 1381558Srgrimes } 1391558Srgrimes } 1401558Srgrimes else if (16%sizeof(size_t) == 0) { /* always true */ 1411558Srgrimes while (len>=16) { 1421558Srgrimes size_t *out_t=(size_t *)out, *iv_t=(size_t *)iv; 1431558Srgrimes 1441558Srgrimes (*block)(in, out, key); 1451558Srgrimes for(n=0; n<16/sizeof(size_t); n++) 1461558Srgrimes out_t[n] ^= iv_t[n]; 1471558Srgrimes iv = in; 1481558Srgrimes len -= 16; 14924359Simp in += 16; 1501558Srgrimes out += 16; 1511558Srgrimes } 1521558Srgrimes } 1531558Srgrimes memcpy(ivec,iv,16); 1541558Srgrimes } else { 1551558Srgrimes if (STRICT_ALIGNMENT && 1561558Srgrimes ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) { 1571558Srgrimes unsigned char c; 1581558Srgrimes while (len>=16) { 1591558Srgrimes (*block)(in, tmp.c, key); 1601558Srgrimes for(n=0; n<16; ++n) { 1611558Srgrimes c = in[n]; 1621856Sdg out[n] = tmp.c[n] ^ ivec[n]; 1631558Srgrimes ivec[n] = c; 1641558Srgrimes } 1651558Srgrimes len -= 16; 1661558Srgrimes in += 16; 1671558Srgrimes out += 16; 1681558Srgrimes } 1691558Srgrimes } 1701558Srgrimes else if (16%sizeof(size_t) == 0) { /* always true */ 1711558Srgrimes while (len>=16) { 1721558Srgrimes size_t c, *out_t=(size_t *)out, *ivec_t=(size_t *)ivec; 1731558Srgrimes const size_t *in_t=(const size_t *)in; 1741558Srgrimes 1751558Srgrimes (*block)(in, tmp.c, key); 1761558Srgrimes for(n=0; n<16/sizeof(size_t); n++) { 1771558Srgrimes c = in_t[n]; 1781558Srgrimes out_t[n] = tmp.t[n] ^ ivec_t[n]; 1791558Srgrimes ivec_t[n] = c; 1801856Sdg } 1811558Srgrimes len -= 16; 1821558Srgrimes in += 16; 1831558Srgrimes out += 16; 1841558Srgrimes } 1851558Srgrimes } 1861558Srgrimes } 1871558Srgrimes#endif 1881558Srgrimes while (len) { 1891558Srgrimes unsigned char c; 1901558Srgrimes (*block)(in, tmp.c, key); 1911558Srgrimes for(n=0; n<16 && n<len; ++n) { 1921558Srgrimes c = in[n]; 1931558Srgrimes out[n] = tmp.c[n] ^ ivec[n]; 1941558Srgrimes ivec[n] = c; 1951558Srgrimes } 1961558Srgrimes if (len<=16) { 1971558Srgrimes for (; n<16; ++n) 1981558Srgrimes ivec[n] = in[n]; 1991558Srgrimes break; 20018914Sfenner } 20118914Sfenner len -= 16; 2021558Srgrimes in += 16; 2031558Srgrimes out += 16; 2041558Srgrimes } 2051558Srgrimes} 2061558Srgrimes