1/* crypto/des/cfb_enc.c */ 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3 * All rights reserved. 4 * 5 * This package is an SSL implementation written 6 * by Eric Young (eay@cryptsoft.com). 7 * The implementation was written so as to conform with Netscapes SSL. 8 * 9 * This library is free for commercial and non-commercial use as long as 10 * the following conditions are aheared to. The following conditions 11 * apply to all code found in this distribution, be it the RC4, RSA, 12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13 * included with this distribution is covered by the same copyright terms 14 * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15 * 16 * Copyright remains Eric Young's, and as such any Copyright notices in 17 * the code are not to be removed. 18 * If this package is used in a product, Eric Young should be given attribution 19 * as the author of the parts of the library used. 20 * This can be in the form of a textual message at program startup or 21 * in documentation (online or textual) provided with the package. 22 * 23 * Redistribution and use in source and binary forms, with or without 24 * modification, are permitted provided that the following conditions 25 * are met: 26 * 1. Redistributions of source code must retain the copyright 27 * notice, this list of conditions and the following disclaimer. 28 * 2. Redistributions in binary form must reproduce the above copyright 29 * notice, this list of conditions and the following disclaimer in the 30 * documentation and/or other materials provided with the distribution. 31 * 3. All advertising materials mentioning features or use of this software 32 * must display the following acknowledgement: 33 * "This product includes cryptographic software written by 34 * Eric Young (eay@cryptsoft.com)" 35 * The word 'cryptographic' can be left out if the rouines from the library 36 * being used are not cryptographic related :-). 37 * 4. If you include any Windows specific code (or a derivative thereof) from 38 * the apps directory (application code) you must include an acknowledgement: 39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40 * 41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51 * SUCH DAMAGE. 52 * 53 * The licence and distribution terms for any publically available version or 54 * derivative of this code cannot be changed. i.e. this code cannot simply be 55 * copied and put under another distribution licence 56 * [including the GNU Public Licence.] 57 */ 58 59#include "e_os.h" 60#include "des_locl.h" 61#include <assert.h> 62 63/* 64 * The input and output are loaded in multiples of 8 bits. What this means is 65 * that if you hame numbits=12 and length=2 the first 12 bits will be 66 * retrieved from the first byte and half the second. The second 12 bits 67 * will come from the 3rd and half the 4th byte. 68 */ 69/* 70 * Until Aug 1 2003 this function did not correctly implement CFB-r, so it 71 * will not be compatible with any encryption prior to that date. Ben. 72 */ 73void DES_cfb_encrypt(const unsigned char *in, unsigned char *out, int numbits, 74 long length, DES_key_schedule *schedule, 75 DES_cblock *ivec, int enc) 76{ 77 register DES_LONG d0, d1, v0, v1; 78 register unsigned long l = length; 79 register int num = numbits / 8, n = (numbits + 7) / 8, i, rem = 80 numbits % 8; 81 DES_LONG ti[2]; 82 unsigned char *iv; 83#ifndef L_ENDIAN 84 unsigned char ovec[16]; 85#else 86 unsigned int sh[4]; 87 unsigned char *ovec = (unsigned char *)sh; 88 89 /* I kind of count that compiler optimizes away this assertioni, */ 90 assert(sizeof(sh[0]) == 4); /* as this holds true for all, */ 91 /* but 16-bit platforms... */ 92 93#endif 94 95 if (numbits <= 0 || numbits > 64) 96 return; 97 iv = &(*ivec)[0]; 98 c2l(iv, v0); 99 c2l(iv, v1); 100 if (enc) { 101 while (l >= (unsigned long)n) { 102 l -= n; 103 ti[0] = v0; 104 ti[1] = v1; 105 DES_encrypt1((DES_LONG *)ti, schedule, DES_ENCRYPT); 106 c2ln(in, d0, d1, n); 107 in += n; 108 d0 ^= ti[0]; 109 d1 ^= ti[1]; 110 l2cn(d0, d1, out, n); 111 out += n; 112 /* 113 * 30-08-94 - eay - changed because l>>32 and l<<32 are bad under 114 * gcc :-( 115 */ 116 if (numbits == 32) { 117 v0 = v1; 118 v1 = d0; 119 } else if (numbits == 64) { 120 v0 = d0; 121 v1 = d1; 122 } else { 123#ifndef L_ENDIAN 124 iv = &ovec[0]; 125 l2c(v0, iv); 126 l2c(v1, iv); 127 l2c(d0, iv); 128 l2c(d1, iv); 129#else 130 sh[0] = v0, sh[1] = v1, sh[2] = d0, sh[3] = d1; 131#endif 132 if (rem == 0) 133 memmove(ovec, ovec + num, 8); 134 else 135 for (i = 0; i < 8; ++i) 136 ovec[i] = ovec[i + num] << rem | 137 ovec[i + num + 1] >> (8 - rem); 138#ifdef L_ENDIAN 139 v0 = sh[0], v1 = sh[1]; 140#else 141 iv = &ovec[0]; 142 c2l(iv, v0); 143 c2l(iv, v1); 144#endif 145 } 146 } 147 } else { 148 while (l >= (unsigned long)n) { 149 l -= n; 150 ti[0] = v0; 151 ti[1] = v1; 152 DES_encrypt1((DES_LONG *)ti, schedule, DES_ENCRYPT); 153 c2ln(in, d0, d1, n); 154 in += n; 155 /* 156 * 30-08-94 - eay - changed because l>>32 and l<<32 are bad under 157 * gcc :-( 158 */ 159 if (numbits == 32) { 160 v0 = v1; 161 v1 = d0; 162 } else if (numbits == 64) { 163 v0 = d0; 164 v1 = d1; 165 } else { 166#ifndef L_ENDIAN 167 iv = &ovec[0]; 168 l2c(v0, iv); 169 l2c(v1, iv); 170 l2c(d0, iv); 171 l2c(d1, iv); 172#else 173 sh[0] = v0, sh[1] = v1, sh[2] = d0, sh[3] = d1; 174#endif 175 if (rem == 0) 176 memmove(ovec, ovec + num, 8); 177 else 178 for (i = 0; i < 8; ++i) 179 ovec[i] = ovec[i + num] << rem | 180 ovec[i + num + 1] >> (8 - rem); 181#ifdef L_ENDIAN 182 v0 = sh[0], v1 = sh[1]; 183#else 184 iv = &ovec[0]; 185 c2l(iv, v0); 186 c2l(iv, v1); 187#endif 188 } 189 d0 ^= ti[0]; 190 d1 ^= ti[1]; 191 l2cn(d0, d1, out, n); 192 out += n; 193 } 194 } 195 iv = &(*ivec)[0]; 196 l2c(v0, iv); 197 l2c(v1, iv); 198 v0 = v1 = d0 = d1 = ti[0] = ti[1] = 0; 199} 200