i_cbc.c revision 296465
139230Sgibbs/* crypto/idea/i_cbc.c */
282168Sken/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
339230Sgibbs * All rights reserved.
439230Sgibbs *
539230Sgibbs * This package is an SSL implementation written
639230Sgibbs * by Eric Young (eay@cryptsoft.com).
739230Sgibbs * The implementation was written so as to conform with Netscapes SSL.
839230Sgibbs *
939230Sgibbs * This library is free for commercial and non-commercial use as long as
1039230Sgibbs * the following conditions are aheared to.  The following conditions
1139230Sgibbs * apply to all code found in this distribution, be it the RC4, RSA,
1239230Sgibbs * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1339230Sgibbs * included with this distribution is covered by the same copyright terms
1439230Sgibbs * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1539230Sgibbs *
1639230Sgibbs * Copyright remains Eric Young's, and as such any Copyright notices in
1739230Sgibbs * the code are not to be removed.
1839230Sgibbs * If this package is used in a product, Eric Young should be given attribution
1939230Sgibbs * as the author of the parts of the library used.
2039230Sgibbs * This can be in the form of a textual message at program startup or
2139230Sgibbs * in documentation (online or textual) provided with the package.
2239230Sgibbs *
2339230Sgibbs * Redistribution and use in source and binary forms, with or without
2439230Sgibbs * modification, are permitted provided that the following conditions
2539230Sgibbs * are met:
2639230Sgibbs * 1. Redistributions of source code must retain the copyright
2756561Scharnier *    notice, this list of conditions and the following disclaimer.
2856561Scharnier * 2. Redistributions in binary form must reproduce the above copyright
2939230Sgibbs *    notice, this list of conditions and the following disclaimer in the
3039230Sgibbs *    documentation and/or other materials provided with the distribution.
3139230Sgibbs * 3. All advertising materials mentioning features or use of this software
3239230Sgibbs *    must display the following acknowledgement:
3339230Sgibbs *    "This product includes cryptographic software written by
341553Srgrimes *     Eric Young (eay@cryptsoft.com)"
351553Srgrimes *    The word 'cryptographic' can be left out if the rouines from the library
361553Srgrimes *    being used are not cryptographic related :-).
371553Srgrimes * 4. If you include any Windows specific code (or a derivative thereof) from
381553Srgrimes *    the apps directory (application code) you must include an acknowledgement:
391553Srgrimes *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
401553Srgrimes *
411553Srgrimes * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
421553Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
431553Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
441553Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
451553Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
461553Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
471553Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
481553Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
491553Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
501553Srgrimes * OUT OF THE USE OF THIS  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
511553Srgrimes * SUCH DAMAGE.
521553Srgrimes *
531553Srgrimes * The licence and distribution terms for any publically available version or
541553Srgrimes * derivative of this code cannot be changed.  i.e. this code cannot simply be
551553Srgrimes * copied and put under another distribution licence
561553Srgrimes * [including the GNU Public Licence.]
571553Srgrimes */
581553Srgrimes
591553Srgrimes#include <openssl/idea.h>
601553Srgrimes#include "idea_lcl.h"
611553Srgrimes
6239230Sgibbsvoid idea_cbc_encrypt(const unsigned char *in, unsigned char *out,
6339230Sgibbs                      long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv,
6439230Sgibbs                      int encrypt)
6539230Sgibbs{
6639230Sgibbs    register unsigned long tin0, tin1;
6739230Sgibbs    register unsigned long tout0, tout1, xor0, xor1;
6839230Sgibbs    register long l = length;
6939230Sgibbs    unsigned long tin[2];
7039230Sgibbs
7139230Sgibbs    if (encrypt) {
7239230Sgibbs        n2l(iv, tout0);
7339230Sgibbs        n2l(iv, tout1);
7439230Sgibbs        iv -= 8;
7539230Sgibbs        for (l -= 8; l >= 0; l -= 8) {
7639230Sgibbs            n2l(in, tin0);
7739230Sgibbs            n2l(in, tin1);
7839230Sgibbs            tin0 ^= tout0;
7939230Sgibbs            tin1 ^= tout1;
8039230Sgibbs            tin[0] = tin0;
8139230Sgibbs            tin[1] = tin1;
8239230Sgibbs            idea_encrypt(tin, ks);
8339230Sgibbs            tout0 = tin[0];
8439230Sgibbs            l2n(tout0, out);
8539230Sgibbs            tout1 = tin[1];
8639230Sgibbs            l2n(tout1, out);
8739230Sgibbs        }
8839230Sgibbs        if (l != -8) {
8939230Sgibbs            n2ln(in, tin0, tin1, l + 8);
9039230Sgibbs            tin0 ^= tout0;
9139230Sgibbs            tin1 ^= tout1;
9239230Sgibbs            tin[0] = tin0;
9339230Sgibbs            tin[1] = tin1;
9439230Sgibbs            idea_encrypt(tin, ks);
9539230Sgibbs            tout0 = tin[0];
9639230Sgibbs            l2n(tout0, out);
971553Srgrimes            tout1 = tin[1];
981553Srgrimes            l2n(tout1, out);
991553Srgrimes        }
10039230Sgibbs        l2n(tout0, iv);
101111008Sphk        l2n(tout1, iv);
10281134Stmm    } else {
1031553Srgrimes        n2l(iv, xor0);
104228661Sdim        n2l(iv, xor1);
105228661Sdim        iv -= 8;
1061553Srgrimes        for (l -= 8; l >= 0; l -= 8) {
1071553Srgrimes            n2l(in, tin0);
108228661Sdim            tin[0] = tin0;
1091553Srgrimes            n2l(in, tin1);
110228661Sdim            tin[1] = tin1;
111228661Sdim            idea_encrypt(tin, ks);
112102067Sbde            tout0 = tin[0] ^ xor0;
1131553Srgrimes            tout1 = tin[1] ^ xor1;
1141553Srgrimes            l2n(tout0, out);
1151553Srgrimes            l2n(tout1, out);
116175562Skeramida            xor0 = tin0;
1171553Srgrimes            xor1 = tin1;
1181553Srgrimes        }
1191553Srgrimes        if (l != -8) {
12039230Sgibbs            n2l(in, tin0);
1211553Srgrimes            tin[0] = tin0;
12239230Sgibbs            n2l(in, tin1);
1231553Srgrimes            tin[1] = tin1;
124181881Sjhb            idea_encrypt(tin, ks);
12582168Sken            tout0 = tin[0] ^ xor0;
126181881Sjhb            tout1 = tin[1] ^ xor1;
1271553Srgrimes            l2nn(tout0, tout1, out, l + 8);
1281553Srgrimes            xor0 = tin0;
1291553Srgrimes            xor1 = tin1;
130175562Skeramida        }
131175562Skeramida        l2n(xor0, iv);
13239230Sgibbs        l2n(xor1, iv);
13339230Sgibbs    }
13439230Sgibbs    tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
13539230Sgibbs    tin[0] = tin[1] = 0;
13683965Sguido}
137175562Skeramida
138175562Skeramidavoid idea_encrypt(unsigned long *d, IDEA_KEY_SCHEDULE *key)
13939371Sdillon{
140157800Smaxim    register IDEA_INT *p;
1411553Srgrimes    register unsigned long x1, x2, x3, x4, t0, t1, ul;
14239230Sgibbs
14339230Sgibbs    x2 = d[0];
14483965Sguido    x1 = (x2 >> 16);
145175562Skeramida    x4 = d[1];
146175562Skeramida    x3 = (x4 >> 16);
14783965Sguido
14882168Sken    p = &(key->data[0][0]);
14939230Sgibbs
15082168Sken    E_IDEA(0);
15182168Sken    E_IDEA(1);
1521553Srgrimes    E_IDEA(2);
15339230Sgibbs    E_IDEA(3);
15439230Sgibbs    E_IDEA(4);
15539230Sgibbs    E_IDEA(5);
15639230Sgibbs    E_IDEA(6);
15739230Sgibbs    E_IDEA(7);
15839230Sgibbs
15939230Sgibbs    x1 &= 0xffff;
16039230Sgibbs    idea_mul(x1, x1, *p, ul);
16139230Sgibbs    p++;
162157800Smaxim
16356561Scharnier    t0 = x3 + *(p++);
16456561Scharnier    t1 = x2 + *(p++);
16539230Sgibbs
1661553Srgrimes    x4 &= 0xffff;
1671553Srgrimes    idea_mul(x4, x4, *p, ul);
16839230Sgibbs
1691553Srgrimes    d[0] = (t0 & 0xffff) | ((x1 & 0xffff) << 16);
170157802Smaxim    d[1] = (x4 & 0xffff) | ((t1 & 0xffff) << 16);
17139230Sgibbs}
17239230Sgibbs