1162911Ssimon/* crypto/camellia/camellia_cfb.c -*- mode:C; c-file-style: "eay" -*- */ 2162911Ssimon/* ==================================================================== 3162911Ssimon * Copyright (c) 2006 The OpenSSL Project. All rights reserved. 4162911Ssimon * 5162911Ssimon * Redistribution and use in source and binary forms, with or without 6162911Ssimon * modification, are permitted provided that the following conditions 7162911Ssimon * are met: 8162911Ssimon * 9162911Ssimon * 1. Redistributions of source code must retain the above copyright 10296465Sdelphij * notice, this list of conditions and the following disclaimer. 11162911Ssimon * 12162911Ssimon * 2. Redistributions in binary form must reproduce the above copyright 13162911Ssimon * notice, this list of conditions and the following disclaimer in 14162911Ssimon * the documentation and/or other materials provided with the 15162911Ssimon * distribution. 16162911Ssimon * 17162911Ssimon * 3. All advertising materials mentioning features or use of this 18162911Ssimon * software must display the following acknowledgment: 19162911Ssimon * "This product includes software developed by the OpenSSL Project 20162911Ssimon * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 21162911Ssimon * 22162911Ssimon * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 23162911Ssimon * endorse or promote products derived from this software without 24162911Ssimon * prior written permission. For written permission, please contact 25162911Ssimon * openssl-core@openssl.org. 26162911Ssimon * 27162911Ssimon * 5. Products derived from this software may not be called "OpenSSL" 28162911Ssimon * nor may "OpenSSL" appear in their names without prior written 29162911Ssimon * permission of the OpenSSL Project. 30162911Ssimon * 31162911Ssimon * 6. Redistributions of any form whatsoever must retain the following 32162911Ssimon * acknowledgment: 33162911Ssimon * "This product includes software developed by the OpenSSL Project 34162911Ssimon * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 35162911Ssimon * 36162911Ssimon * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 37162911Ssimon * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 38162911Ssimon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 39162911Ssimon * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 40162911Ssimon * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 41162911Ssimon * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 42162911Ssimon * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 43162911Ssimon * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 44162911Ssimon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 45162911Ssimon * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 46162911Ssimon * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 47162911Ssimon * OF THE POSSIBILITY OF SUCH DAMAGE. 48162911Ssimon * ==================================================================== 49162911Ssimon * 50162911Ssimon */ 51162911Ssimon/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 52162911Ssimon * All rights reserved. 53162911Ssimon * 54162911Ssimon * This package is an SSL implementation written 55162911Ssimon * by Eric Young (eay@cryptsoft.com). 56162911Ssimon * The implementation was written so as to conform with Netscapes SSL. 57296465Sdelphij * 58162911Ssimon * This library is free for commercial and non-commercial use as long as 59162911Ssimon * the following conditions are aheared to. The following conditions 60162911Ssimon * apply to all code found in this distribution, be it the RC4, RSA, 61162911Ssimon * lhash, DES, etc., code; not just the SSL code. The SSL documentation 62162911Ssimon * included with this distribution is covered by the same copyright terms 63162911Ssimon * except that the holder is Tim Hudson (tjh@cryptsoft.com). 64296465Sdelphij * 65162911Ssimon * Copyright remains Eric Young's, and as such any Copyright notices in 66162911Ssimon * the code are not to be removed. 67162911Ssimon * If this package is used in a product, Eric Young should be given attribution 68162911Ssimon * as the author of the parts of the library used. 69162911Ssimon * This can be in the form of a textual message at program startup or 70162911Ssimon * in documentation (online or textual) provided with the package. 71296465Sdelphij * 72162911Ssimon * Redistribution and use in source and binary forms, with or without 73162911Ssimon * modification, are permitted provided that the following conditions 74162911Ssimon * are met: 75162911Ssimon * 1. Redistributions of source code must retain the copyright 76162911Ssimon * notice, this list of conditions and the following disclaimer. 77162911Ssimon * 2. Redistributions in binary form must reproduce the above copyright 78162911Ssimon * notice, this list of conditions and the following disclaimer in the 79162911Ssimon * documentation and/or other materials provided with the distribution. 80162911Ssimon * 3. All advertising materials mentioning features or use of this software 81162911Ssimon * must display the following acknowledgement: 82162911Ssimon * "This product includes cryptographic software written by 83162911Ssimon * Eric Young (eay@cryptsoft.com)" 84162911Ssimon * The word 'cryptographic' can be left out if the rouines from the library 85162911Ssimon * being used are not cryptographic related :-). 86296465Sdelphij * 4. If you include any Windows specific code (or a derivative thereof) from 87162911Ssimon * the apps directory (application code) you must include an acknowledgement: 88162911Ssimon * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 89296465Sdelphij * 90162911Ssimon * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 91162911Ssimon * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 92162911Ssimon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 93162911Ssimon * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 94162911Ssimon * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 95162911Ssimon * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 96162911Ssimon * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 97162911Ssimon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 98162911Ssimon * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 99162911Ssimon * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 100162911Ssimon * SUCH DAMAGE. 101296465Sdelphij * 102162911Ssimon * The licence and distribution terms for any publically available version or 103162911Ssimon * derivative of this code cannot be changed. i.e. this code cannot simply be 104162911Ssimon * copied and put under another distribution licence 105162911Ssimon * [including the GNU Public Licence.] 106162911Ssimon */ 107162911Ssimon 108162911Ssimon#ifndef CAMELLIA_DEBUG 109162911Ssimon# ifndef NDEBUG 110162911Ssimon# define NDEBUG 111162911Ssimon# endif 112162911Ssimon#endif 113162911Ssimon#include <assert.h> 114162911Ssimon#include <string.h> 115162911Ssimon 116162911Ssimon#include <openssl/camellia.h> 117162911Ssimon#include "cmll_locl.h" 118162911Ssimon#include "e_os.h" 119162911Ssimon 120296465Sdelphij/* 121296465Sdelphij * The input and output encrypted as though 128bit cfb mode is being used. 122296465Sdelphij * The extra state information to record how much of the 128bit block we have 123296465Sdelphij * used is contained in *num; 124162911Ssimon */ 125162911Ssimon 126162911Ssimonvoid Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out, 127296465Sdelphij const unsigned long length, 128296465Sdelphij const CAMELLIA_KEY *key, unsigned char *ivec, 129296465Sdelphij int *num, const int enc) 130296465Sdelphij{ 131162911Ssimon 132296465Sdelphij unsigned int n; 133296465Sdelphij unsigned long l = length; 134296465Sdelphij unsigned char c; 135162911Ssimon 136296465Sdelphij assert(in && out && key && ivec && num); 137162911Ssimon 138296465Sdelphij n = *num; 139162911Ssimon 140296465Sdelphij if (enc) { 141296465Sdelphij while (l--) { 142296465Sdelphij if (n == 0) { 143296465Sdelphij Camellia_encrypt(ivec, ivec, key); 144296465Sdelphij } 145296465Sdelphij ivec[n] = *(out++) = *(in++) ^ ivec[n]; 146296465Sdelphij n = (n + 1) % CAMELLIA_BLOCK_SIZE; 147296465Sdelphij } 148296465Sdelphij } else { 149296465Sdelphij while (l--) { 150296465Sdelphij if (n == 0) { 151296465Sdelphij Camellia_encrypt(ivec, ivec, key); 152296465Sdelphij } 153296465Sdelphij c = *(in); 154296465Sdelphij *(out++) = *(in++) ^ ivec[n]; 155296465Sdelphij ivec[n] = c; 156296465Sdelphij n = (n + 1) % CAMELLIA_BLOCK_SIZE; 157296465Sdelphij } 158296465Sdelphij } 159162911Ssimon 160296465Sdelphij *num = n; 161296465Sdelphij} 162162911Ssimon 163296465Sdelphij/* 164296465Sdelphij * This expects a single block of size nbits for both in and out. Note that 165296465Sdelphij * it corrupts any extra bits in the last byte of out 166296465Sdelphij */ 167296465Sdelphijvoid Camellia_cfbr_encrypt_block(const unsigned char *in, unsigned char *out, 168296465Sdelphij const int nbits, const CAMELLIA_KEY *key, 169296465Sdelphij unsigned char *ivec, const int enc) 170296465Sdelphij{ 171296465Sdelphij int n, rem, num; 172296465Sdelphij unsigned char ovec[CAMELLIA_BLOCK_SIZE * 2]; 173162911Ssimon 174296465Sdelphij if (nbits <= 0 || nbits > 128) 175296465Sdelphij return; 176162911Ssimon 177296465Sdelphij /* fill in the first half of the new IV with the current IV */ 178296465Sdelphij memcpy(ovec, ivec, CAMELLIA_BLOCK_SIZE); 179296465Sdelphij /* construct the new IV */ 180296465Sdelphij Camellia_encrypt(ivec, ivec, key); 181296465Sdelphij num = (nbits + 7) / 8; 182296465Sdelphij if (enc) /* encrypt the input */ 183296465Sdelphij for (n = 0; n < num; ++n) 184296465Sdelphij out[n] = (ovec[CAMELLIA_BLOCK_SIZE + n] = in[n] ^ ivec[n]); 185296465Sdelphij else /* decrypt the input */ 186296465Sdelphij for (n = 0; n < num; ++n) 187296465Sdelphij out[n] = (ovec[CAMELLIA_BLOCK_SIZE + n] = in[n]) ^ ivec[n]; 188296465Sdelphij /* shift ovec left... */ 189296465Sdelphij rem = nbits % 8; 190296465Sdelphij num = nbits / 8; 191296465Sdelphij if (rem == 0) 192296465Sdelphij memcpy(ivec, ovec + num, CAMELLIA_BLOCK_SIZE); 193296465Sdelphij else 194296465Sdelphij for (n = 0; n < CAMELLIA_BLOCK_SIZE; ++n) 195296465Sdelphij ivec[n] = ovec[n + num] << rem | ovec[n + num + 1] >> (8 - rem); 196162911Ssimon 197296465Sdelphij /* it is not necessary to cleanse ovec, since the IV is not secret */ 198296465Sdelphij} 199162911Ssimon 200162911Ssimon/* N.B. This expects the input to be packed, MS bit first */ 201162911Ssimonvoid Camellia_cfb1_encrypt(const unsigned char *in, unsigned char *out, 202296465Sdelphij const unsigned long length, 203296465Sdelphij const CAMELLIA_KEY *key, unsigned char *ivec, 204296465Sdelphij int *num, const int enc) 205296465Sdelphij{ 206296465Sdelphij unsigned int n; 207296465Sdelphij unsigned char c[1], d[1]; 208162911Ssimon 209296465Sdelphij assert(in && out && key && ivec && num); 210296465Sdelphij assert(*num == 0); 211162911Ssimon 212296465Sdelphij memset(out, 0, (length + 7) / 8); 213296465Sdelphij for (n = 0; n < length; ++n) { 214296465Sdelphij c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0; 215296465Sdelphij Camellia_cfbr_encrypt_block(c, d, 1, key, ivec, enc); 216296465Sdelphij out[n / 8] = 217296465Sdelphij (out[n / 8] & ~(1 << (7 - n % 8))) | ((d[0] & 0x80) >> (n % 8)); 218296465Sdelphij } 219296465Sdelphij} 220162911Ssimon 221162911Ssimonvoid Camellia_cfb8_encrypt(const unsigned char *in, unsigned char *out, 222296465Sdelphij const unsigned long length, 223296465Sdelphij const CAMELLIA_KEY *key, unsigned char *ivec, 224296465Sdelphij int *num, const int enc) 225296465Sdelphij{ 226296465Sdelphij unsigned int n; 227162911Ssimon 228296465Sdelphij assert(in && out && key && ivec && num); 229296465Sdelphij assert(*num == 0); 230162911Ssimon 231296465Sdelphij for (n = 0; n < length; ++n) 232296465Sdelphij Camellia_cfbr_encrypt_block(&in[n], &out[n], 8, key, ivec, enc); 233296465Sdelphij} 234