1238384Sjkim/* ==================================================================== 2238384Sjkim * Copyright (c) 2008 The OpenSSL Project. All rights reserved. 3238384Sjkim * 4238384Sjkim * Redistribution and use in source and binary forms, with or without 5238384Sjkim * modification, are permitted provided that the following conditions 6238384Sjkim * are met: 7238384Sjkim * 8238384Sjkim * 1. Redistributions of source code must retain the above copyright 9280297Sjkim * notice, this list of conditions and the following disclaimer. 10238384Sjkim * 11238384Sjkim * 2. Redistributions in binary form must reproduce the above copyright 12238384Sjkim * notice, this list of conditions and the following disclaimer in 13238384Sjkim * the documentation and/or other materials provided with the 14238384Sjkim * distribution. 15238384Sjkim * 16238384Sjkim * 3. All advertising materials mentioning features or use of this 17238384Sjkim * software must display the following acknowledgment: 18238384Sjkim * "This product includes software developed by the OpenSSL Project 19238384Sjkim * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 20238384Sjkim * 21238384Sjkim * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 22238384Sjkim * endorse or promote products derived from this software without 23238384Sjkim * prior written permission. For written permission, please contact 24238384Sjkim * openssl-core@openssl.org. 25238384Sjkim * 26238384Sjkim * 5. Products derived from this software may not be called "OpenSSL" 27238384Sjkim * nor may "OpenSSL" appear in their names without prior written 28238384Sjkim * permission of the OpenSSL Project. 29238384Sjkim * 30238384Sjkim * 6. Redistributions of any form whatsoever must retain the following 31238384Sjkim * acknowledgment: 32238384Sjkim * "This product includes software developed by the OpenSSL Project 33238384Sjkim * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 34238384Sjkim * 35238384Sjkim * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 36238384Sjkim * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 37238384Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 38238384Sjkim * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 39238384Sjkim * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 40238384Sjkim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 41238384Sjkim * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 42238384Sjkim * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 43238384Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 44238384Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 45238384Sjkim * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 46238384Sjkim * OF THE POSSIBILITY OF SUCH DAMAGE. 47238384Sjkim * ==================================================================== 48238384Sjkim * 49238384Sjkim */ 50238384Sjkim 51238384Sjkim#include <openssl/crypto.h> 52238384Sjkim#include "modes_lcl.h" 53238384Sjkim#include <string.h> 54238384Sjkim 55238384Sjkim#ifndef MODES_DEBUG 56238384Sjkim# ifndef NDEBUG 57238384Sjkim# define NDEBUG 58238384Sjkim# endif 59238384Sjkim#endif 60238384Sjkim#include <assert.h> 61238384Sjkim 62290207Sjkim#if !defined(STRICT_ALIGNMENT) && !defined(PEDANTIC) 63280297Sjkim# define STRICT_ALIGNMENT 0 64238384Sjkim#endif 65238384Sjkim 66238384Sjkimvoid CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out, 67280297Sjkim size_t len, const void *key, 68280297Sjkim unsigned char ivec[16], block128_f block) 69238384Sjkim{ 70280297Sjkim size_t n; 71280297Sjkim const unsigned char *iv = ivec; 72238384Sjkim 73280297Sjkim assert(in && out && key && ivec); 74238384Sjkim 75238384Sjkim#if !defined(OPENSSL_SMALL_FOOTPRINT) 76280297Sjkim if (STRICT_ALIGNMENT && 77280297Sjkim ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) { 78280297Sjkim while (len >= 16) { 79280297Sjkim for (n = 0; n < 16; ++n) 80280297Sjkim out[n] = in[n] ^ iv[n]; 81280297Sjkim (*block) (out, out, key); 82280297Sjkim iv = out; 83280297Sjkim len -= 16; 84280297Sjkim in += 16; 85280297Sjkim out += 16; 86280297Sjkim } 87280297Sjkim } else { 88280297Sjkim while (len >= 16) { 89280297Sjkim for (n = 0; n < 16; n += sizeof(size_t)) 90280297Sjkim *(size_t *)(out + n) = 91280297Sjkim *(size_t *)(in + n) ^ *(size_t *)(iv + n); 92280297Sjkim (*block) (out, out, key); 93280297Sjkim iv = out; 94280297Sjkim len -= 16; 95280297Sjkim in += 16; 96280297Sjkim out += 16; 97280297Sjkim } 98280297Sjkim } 99238384Sjkim#endif 100280297Sjkim while (len) { 101280297Sjkim for (n = 0; n < 16 && n < len; ++n) 102280297Sjkim out[n] = in[n] ^ iv[n]; 103280297Sjkim for (; n < 16; ++n) 104280297Sjkim out[n] = iv[n]; 105280297Sjkim (*block) (out, out, key); 106280297Sjkim iv = out; 107280297Sjkim if (len <= 16) 108280297Sjkim break; 109280297Sjkim len -= 16; 110280297Sjkim in += 16; 111280297Sjkim out += 16; 112280297Sjkim } 113280297Sjkim memcpy(ivec, iv, 16); 114238384Sjkim} 115238384Sjkim 116238384Sjkimvoid CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out, 117280297Sjkim size_t len, const void *key, 118280297Sjkim unsigned char ivec[16], block128_f block) 119238384Sjkim{ 120280297Sjkim size_t n; 121280297Sjkim union { 122280297Sjkim size_t t[16 / sizeof(size_t)]; 123280297Sjkim unsigned char c[16]; 124280297Sjkim } tmp; 125238384Sjkim 126280297Sjkim assert(in && out && key && ivec); 127238384Sjkim 128238384Sjkim#if !defined(OPENSSL_SMALL_FOOTPRINT) 129280297Sjkim if (in != out) { 130280297Sjkim const unsigned char *iv = ivec; 131238384Sjkim 132280297Sjkim if (STRICT_ALIGNMENT && 133280297Sjkim ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) { 134280297Sjkim while (len >= 16) { 135280297Sjkim (*block) (in, out, key); 136280297Sjkim for (n = 0; n < 16; ++n) 137280297Sjkim out[n] ^= iv[n]; 138280297Sjkim iv = in; 139280297Sjkim len -= 16; 140280297Sjkim in += 16; 141280297Sjkim out += 16; 142280297Sjkim } 143280297Sjkim } else if (16 % sizeof(size_t) == 0) { /* always true */ 144280297Sjkim while (len >= 16) { 145280297Sjkim size_t *out_t = (size_t *)out, *iv_t = (size_t *)iv; 146261037Sjkim 147280297Sjkim (*block) (in, out, key); 148280297Sjkim for (n = 0; n < 16 / sizeof(size_t); n++) 149280297Sjkim out_t[n] ^= iv_t[n]; 150280297Sjkim iv = in; 151280297Sjkim len -= 16; 152280297Sjkim in += 16; 153280297Sjkim out += 16; 154280297Sjkim } 155280297Sjkim } 156280297Sjkim memcpy(ivec, iv, 16); 157280297Sjkim } else { 158280297Sjkim if (STRICT_ALIGNMENT && 159280297Sjkim ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) { 160280297Sjkim unsigned char c; 161280297Sjkim while (len >= 16) { 162280297Sjkim (*block) (in, tmp.c, key); 163280297Sjkim for (n = 0; n < 16; ++n) { 164280297Sjkim c = in[n]; 165280297Sjkim out[n] = tmp.c[n] ^ ivec[n]; 166280297Sjkim ivec[n] = c; 167280297Sjkim } 168280297Sjkim len -= 16; 169280297Sjkim in += 16; 170280297Sjkim out += 16; 171280297Sjkim } 172280297Sjkim } else if (16 % sizeof(size_t) == 0) { /* always true */ 173280297Sjkim while (len >= 16) { 174280297Sjkim size_t c, *out_t = (size_t *)out, *ivec_t = (size_t *)ivec; 175280297Sjkim const size_t *in_t = (const size_t *)in; 176261037Sjkim 177280297Sjkim (*block) (in, tmp.c, key); 178280297Sjkim for (n = 0; n < 16 / sizeof(size_t); n++) { 179280297Sjkim c = in_t[n]; 180280297Sjkim out_t[n] = tmp.t[n] ^ ivec_t[n]; 181280297Sjkim ivec_t[n] = c; 182280297Sjkim } 183280297Sjkim len -= 16; 184280297Sjkim in += 16; 185280297Sjkim out += 16; 186280297Sjkim } 187280297Sjkim } 188280297Sjkim } 189238384Sjkim#endif 190280297Sjkim while (len) { 191280297Sjkim unsigned char c; 192280297Sjkim (*block) (in, tmp.c, key); 193280297Sjkim for (n = 0; n < 16 && n < len; ++n) { 194280297Sjkim c = in[n]; 195280297Sjkim out[n] = tmp.c[n] ^ ivec[n]; 196280297Sjkim ivec[n] = c; 197280297Sjkim } 198280297Sjkim if (len <= 16) { 199280297Sjkim for (; n < 16; ++n) 200280297Sjkim ivec[n] = in[n]; 201280297Sjkim break; 202280297Sjkim } 203280297Sjkim len -= 16; 204280297Sjkim in += 16; 205280297Sjkim out += 16; 206280297Sjkim } 207238384Sjkim} 208