1e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * All rights reserved. 3e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * 4e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * This package is an SSL implementation written 5e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * by Eric Young (eay@cryptsoft.com). 6e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * The implementation was written so as to conform with Netscapes SSL. 7e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * 8e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * This library is free for commercial and non-commercial use as long as 9e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * the following conditions are aheared to. The following conditions 10e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * apply to all code found in this distribution, be it the RC4, RSA, 11e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * lhash, DES, etc., code; not just the SSL code. The SSL documentation 12e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * included with this distribution is covered by the same copyright terms 13e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * except that the holder is Tim Hudson (tjh@cryptsoft.com). 14e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * 15e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * Copyright remains Eric Young's, and as such any Copyright notices in 16e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * the code are not to be removed. 17e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * If this package is used in a product, Eric Young should be given attribution 18e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * as the author of the parts of the library used. 19e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * This can be in the form of a textual message at program startup or 20e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * in documentation (online or textual) provided with the package. 21e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * 22e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * Redistribution and use in source and binary forms, with or without 23e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * modification, are permitted provided that the following conditions 24e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * are met: 25e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * 1. Redistributions of source code must retain the copyright 26e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * notice, this list of conditions and the following disclaimer. 27e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * 2. Redistributions in binary form must reproduce the above copyright 28e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * notice, this list of conditions and the following disclaimer in the 29e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * documentation and/or other materials provided with the distribution. 30e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * 3. All advertising materials mentioning features or use of this software 31e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * must display the following acknowledgement: 32e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * "This product includes cryptographic software written by 33e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * Eric Young (eay@cryptsoft.com)" 34e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * The word 'cryptographic' can be left out if the rouines from the library 35e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * being used are not cryptographic related :-). 36e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * 4. If you include any Windows specific code (or a derivative thereof) from 37e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * the apps directory (application code) you must include an acknowledgement: 38e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 39e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * 40e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 41e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 43e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 44e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 45e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 46e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 48e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 49e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 50e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * SUCH DAMAGE. 51e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * 52e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * The licence and distribution terms for any publically available version or 53e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * derivative of this code cannot be changed. i.e. this code cannot simply be 54e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * copied and put under another distribution licence 55e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * [including the GNU Public Licence.]. */ 56e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 57e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#include <openssl/cast.h> 58e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 59e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#if defined(OPENSSL_WINDOWS) 60e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#pragma warning(push, 3) 61e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#include <intrin.h> 62e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#pragma warning(pop) 63e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#endif 64e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 654139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley#include "internal.h" 66e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#include "../macros.h" 67e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 68e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 69e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleyvoid CAST_ecb_encrypt(const uint8_t *in, uint8_t *out, const CAST_KEY *ks, 70e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley int enc) { 71e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley uint32_t d[2]; 72e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 73e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley n2l(in, d[0]); 74e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley n2l(in, d[1]); 75e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley if (enc) { 76e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley CAST_encrypt(d, ks); 77e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } else { 78e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley CAST_decrypt(d, ks); 79e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 80e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley l2n(d[0], out); 81e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley l2n(d[1], out); 82e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley} 83e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 84e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#if defined(OPENSSL_WINDOWS) && defined(_MSC_VER) 85e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#define ROTL(a, n) (_lrotl(a, n)) 86e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#else 87e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#define ROTL(a, n) ((((a) << (n)) | ((a) >> ((-(n))&31))) & 0xffffffffL) 88e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#endif 89e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 90e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#define E_CAST(n, key, L, R, OP1, OP2, OP3) \ 91e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley { \ 92e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley uint32_t a, b, c, d; \ 93e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley t = (key[n * 2] OP1 R) & 0xffffffff; \ 94e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley t = ROTL(t, (key[n * 2 + 1])); \ 95e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley a = CAST_S_table0[(t >> 8) & 0xff]; \ 96e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley b = CAST_S_table1[(t)&0xff]; \ 97e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley c = CAST_S_table2[(t >> 24) & 0xff]; \ 98e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley d = CAST_S_table3[(t >> 16) & 0xff]; \ 99e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley L ^= (((((a OP2 b)&0xffffffffL)OP3 c) & 0xffffffffL)OP1 d) & 0xffffffffL; \ 100e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 101e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 102e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleyvoid CAST_encrypt(uint32_t *data, const CAST_KEY *key) { 103e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley uint32_t l, r, t; 104e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley const uint32_t *k; 105e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 106e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley k = &key->data[0]; 107e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley l = data[0]; 108e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley r = data[1]; 109e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 110e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley E_CAST(0, k, l, r, +, ^, -); 111e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley E_CAST(1, k, r, l, ^, -, +); 112e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley E_CAST(2, k, l, r, -, +, ^); 113e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley E_CAST(3, k, r, l, +, ^, -); 114e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley E_CAST(4, k, l, r, ^, -, +); 115e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley E_CAST(5, k, r, l, -, +, ^); 116e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley E_CAST(6, k, l, r, +, ^, -); 117e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley E_CAST(7, k, r, l, ^, -, +); 118e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley E_CAST(8, k, l, r, -, +, ^); 119e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley E_CAST(9, k, r, l, +, ^, -); 120e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley E_CAST(10, k, l, r, ^, -, +); 121e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley E_CAST(11, k, r, l, -, +, ^); 122e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 123e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley if (!key->short_key) { 124e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley E_CAST(12, k, l, r, +, ^, -); 125e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley E_CAST(13, k, r, l, ^, -, +); 126e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley E_CAST(14, k, l, r, -, +, ^); 127e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley E_CAST(15, k, r, l, +, ^, -); 128e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 129e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 130e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley data[1] = l & 0xffffffffL; 131e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley data[0] = r & 0xffffffffL; 132e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley} 133e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 134e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleyvoid CAST_decrypt(uint32_t *data, const CAST_KEY *key) { 135e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley uint32_t l, r, t; 136e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley const uint32_t *k; 137e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 138e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley k = &key->data[0]; 139e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley l = data[0]; 140e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley r = data[1]; 141e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 142e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley if (!key->short_key) { 143e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley E_CAST(15, k, l, r, +, ^, -); 144e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley E_CAST(14, k, r, l, -, +, ^); 145e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley E_CAST(13, k, l, r, ^, -, +); 146e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley E_CAST(12, k, r, l, +, ^, -); 147e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 148e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 149e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley E_CAST(11, k, l, r, -, +, ^); 150e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley E_CAST(10, k, r, l, ^, -, +); 151e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley E_CAST(9, k, l, r, +, ^, -); 152e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley E_CAST(8, k, r, l, -, +, ^); 153e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley E_CAST(7, k, l, r, ^, -, +); 154e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley E_CAST(6, k, r, l, +, ^, -); 155e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley E_CAST(5, k, l, r, -, +, ^); 156e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley E_CAST(4, k, r, l, ^, -, +); 157e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley E_CAST(3, k, l, r, +, ^, -); 158e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley E_CAST(2, k, r, l, -, +, ^); 159e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley E_CAST(1, k, l, r, ^, -, +); 160e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley E_CAST(0, k, r, l, +, ^, -); 161e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 162e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley data[1] = l & 0xffffffffL; 163e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley data[0] = r & 0xffffffffL; 164e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley} 165e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 166e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleyvoid CAST_cbc_encrypt(const uint8_t *in, uint8_t *out, long length, 167e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley const CAST_KEY *ks, uint8_t *iv, int enc) { 168e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley uint32_t tin0, tin1; 169e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley uint32_t tout0, tout1, xor0, xor1; 170e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley long l = length; 171e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley uint32_t tin[2]; 172e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 173e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley if (enc) { 174e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley n2l(iv, tout0); 175e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley n2l(iv, tout1); 176e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley iv -= 8; 177e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley for (l -= 8; l >= 0; l -= 8) { 178e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley n2l(in, tin0); 179e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley n2l(in, tin1); 180e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley tin0 ^= tout0; 181e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley tin1 ^= tout1; 182e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley tin[0] = tin0; 183e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley tin[1] = tin1; 184e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley CAST_encrypt(tin, ks); 185e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley tout0 = tin[0]; 186e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley tout1 = tin[1]; 187e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley l2n(tout0, out); 188e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley l2n(tout1, out); 189e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 190e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley if (l != -8) { 191e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley n2ln(in, tin0, tin1, l + 8); 192e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley tin0 ^= tout0; 193e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley tin1 ^= tout1; 194e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley tin[0] = tin0; 195e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley tin[1] = tin1; 196e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley CAST_encrypt(tin, ks); 197e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley tout0 = tin[0]; 198e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley tout1 = tin[1]; 199e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley l2n(tout0, out); 200e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley l2n(tout1, out); 201e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 202e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley l2n(tout0, iv); 203e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley l2n(tout1, iv); 204e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } else { 205e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley n2l(iv, xor0); 206e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley n2l(iv, xor1); 207e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley iv -= 8; 208e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley for (l -= 8; l >= 0; l -= 8) { 209e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley n2l(in, tin0); 210e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley n2l(in, tin1); 211e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley tin[0] = tin0; 212e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley tin[1] = tin1; 213e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley CAST_decrypt(tin, ks); 214e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley tout0 = tin[0] ^ xor0; 215e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley tout1 = tin[1] ^ xor1; 216e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley l2n(tout0, out); 217e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley l2n(tout1, out); 218e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley xor0 = tin0; 219e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley xor1 = tin1; 220e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 221e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley if (l != -8) { 222e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley n2l(in, tin0); 223e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley n2l(in, tin1); 224e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley tin[0] = tin0; 225e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley tin[1] = tin1; 226e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley CAST_decrypt(tin, ks); 227e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley tout0 = tin[0] ^ xor0; 228e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley tout1 = tin[1] ^ xor1; 229e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley l2nn(tout0, tout1, out, l + 8); 230e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley xor0 = tin0; 231e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley xor1 = tin1; 232e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 233e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley l2n(xor0, iv); 234e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley l2n(xor1, iv); 235e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 236e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; 237e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley tin[0] = tin[1] = 0; 238e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley} 239e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 240e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#define CAST_exp(l, A, a, n) \ 241e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley A[n / 4] = l; \ 242e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley a[n + 3] = (l)&0xff; \ 243e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley a[n + 2] = (l >> 8) & 0xff; \ 244e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley a[n + 1] = (l >> 16) & 0xff; \ 245e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley a[n + 0] = (l >> 24) & 0xff; 246e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#define S4 CAST_S_table4 247e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#define S5 CAST_S_table5 248e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#define S6 CAST_S_table6 249e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#define S7 CAST_S_table7 250e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 251e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleyvoid CAST_set_key(CAST_KEY *key, size_t len, const uint8_t *data) { 252e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley uint32_t x[16]; 253e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley uint32_t z[16]; 254e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley uint32_t k[32]; 255e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley uint32_t X[4], Z[4]; 256e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley uint32_t l, *K; 257e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley size_t i; 258e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 259e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley for (i = 0; i < 16; i++) { 260e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley x[i] = 0; 261e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 262e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 263e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley if (len > 16) { 264e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley len = 16; 265e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 266e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 267e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley for (i = 0; i < len; i++) { 268e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley x[i] = data[i]; 269e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 270e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 271e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley if (len <= 10) { 272e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley key->short_key = 1; 273e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } else { 274e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley key->short_key = 0; 275e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 276e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 277e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley K = &k[0]; 278e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley X[0] = ((x[0] << 24) | (x[1] << 16) | (x[2] << 8) | x[3]) & 0xffffffffL; 279e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley X[1] = ((x[4] << 24) | (x[5] << 16) | (x[6] << 8) | x[7]) & 0xffffffffL; 280e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley X[2] = ((x[8] << 24) | (x[9] << 16) | (x[10] << 8) | x[11]) & 0xffffffffL; 281e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley X[3] = ((x[12] << 24) | (x[13] << 16) | (x[14] << 8) | x[15]) & 0xffffffffL; 282e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 283e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley for (;;) { 284e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley l = X[0] ^ S4[x[13]] ^ S5[x[15]] ^ S6[x[12]] ^ S7[x[14]] ^ S6[x[8]]; 285e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley CAST_exp(l, Z, z, 0); 286e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley l = X[2] ^ S4[z[0]] ^ S5[z[2]] ^ S6[z[1]] ^ S7[z[3]] ^ S7[x[10]]; 287e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley CAST_exp(l, Z, z, 4); 288e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley l = X[3] ^ S4[z[7]] ^ S5[z[6]] ^ S6[z[5]] ^ S7[z[4]] ^ S4[x[9]]; 289e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley CAST_exp(l, Z, z, 8); 290e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley l = X[1] ^ S4[z[10]] ^ S5[z[9]] ^ S6[z[11]] ^ S7[z[8]] ^ S5[x[11]]; 291e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley CAST_exp(l, Z, z, 12); 292e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 293e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley K[0] = S4[z[8]] ^ S5[z[9]] ^ S6[z[7]] ^ S7[z[6]] ^ S4[z[2]]; 294e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley K[1] = S4[z[10]] ^ S5[z[11]] ^ S6[z[5]] ^ S7[z[4]] ^ S5[z[6]]; 295e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley K[2] = S4[z[12]] ^ S5[z[13]] ^ S6[z[3]] ^ S7[z[2]] ^ S6[z[9]]; 296e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley K[3] = S4[z[14]] ^ S5[z[15]] ^ S6[z[1]] ^ S7[z[0]] ^ S7[z[12]]; 297e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 298e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley l = Z[2] ^ S4[z[5]] ^ S5[z[7]] ^ S6[z[4]] ^ S7[z[6]] ^ S6[z[0]]; 299e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley CAST_exp(l, X, x, 0); 300e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley l = Z[0] ^ S4[x[0]] ^ S5[x[2]] ^ S6[x[1]] ^ S7[x[3]] ^ S7[z[2]]; 301e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley CAST_exp(l, X, x, 4); 302e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley l = Z[1] ^ S4[x[7]] ^ S5[x[6]] ^ S6[x[5]] ^ S7[x[4]] ^ S4[z[1]]; 303e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley CAST_exp(l, X, x, 8); 304e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley l = Z[3] ^ S4[x[10]] ^ S5[x[9]] ^ S6[x[11]] ^ S7[x[8]] ^ S5[z[3]]; 305e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley CAST_exp(l, X, x, 12); 306e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 307e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley K[4] = S4[x[3]] ^ S5[x[2]] ^ S6[x[12]] ^ S7[x[13]] ^ S4[x[8]]; 308e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley K[5] = S4[x[1]] ^ S5[x[0]] ^ S6[x[14]] ^ S7[x[15]] ^ S5[x[13]]; 309e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley K[6] = S4[x[7]] ^ S5[x[6]] ^ S6[x[8]] ^ S7[x[9]] ^ S6[x[3]]; 310e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley K[7] = S4[x[5]] ^ S5[x[4]] ^ S6[x[10]] ^ S7[x[11]] ^ S7[x[7]]; 311e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 312e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley l = X[0] ^ S4[x[13]] ^ S5[x[15]] ^ S6[x[12]] ^ S7[x[14]] ^ S6[x[8]]; 313e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley CAST_exp(l, Z, z, 0); 314e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley l = X[2] ^ S4[z[0]] ^ S5[z[2]] ^ S6[z[1]] ^ S7[z[3]] ^ S7[x[10]]; 315e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley CAST_exp(l, Z, z, 4); 316e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley l = X[3] ^ S4[z[7]] ^ S5[z[6]] ^ S6[z[5]] ^ S7[z[4]] ^ S4[x[9]]; 317e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley CAST_exp(l, Z, z, 8); 318e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley l = X[1] ^ S4[z[10]] ^ S5[z[9]] ^ S6[z[11]] ^ S7[z[8]] ^ S5[x[11]]; 319e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley CAST_exp(l, Z, z, 12); 320e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 321e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley K[8] = S4[z[3]] ^ S5[z[2]] ^ S6[z[12]] ^ S7[z[13]] ^ S4[z[9]]; 322e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley K[9] = S4[z[1]] ^ S5[z[0]] ^ S6[z[14]] ^ S7[z[15]] ^ S5[z[12]]; 323e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley K[10] = S4[z[7]] ^ S5[z[6]] ^ S6[z[8]] ^ S7[z[9]] ^ S6[z[2]]; 324e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley K[11] = S4[z[5]] ^ S5[z[4]] ^ S6[z[10]] ^ S7[z[11]] ^ S7[z[6]]; 325e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 326e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley l = Z[2] ^ S4[z[5]] ^ S5[z[7]] ^ S6[z[4]] ^ S7[z[6]] ^ S6[z[0]]; 327e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley CAST_exp(l, X, x, 0); 328e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley l = Z[0] ^ S4[x[0]] ^ S5[x[2]] ^ S6[x[1]] ^ S7[x[3]] ^ S7[z[2]]; 329e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley CAST_exp(l, X, x, 4); 330e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley l = Z[1] ^ S4[x[7]] ^ S5[x[6]] ^ S6[x[5]] ^ S7[x[4]] ^ S4[z[1]]; 331e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley CAST_exp(l, X, x, 8); 332e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley l = Z[3] ^ S4[x[10]] ^ S5[x[9]] ^ S6[x[11]] ^ S7[x[8]] ^ S5[z[3]]; 333e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley CAST_exp(l, X, x, 12); 334e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 335e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley K[12] = S4[x[8]] ^ S5[x[9]] ^ S6[x[7]] ^ S7[x[6]] ^ S4[x[3]]; 336e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley K[13] = S4[x[10]] ^ S5[x[11]] ^ S6[x[5]] ^ S7[x[4]] ^ S5[x[7]]; 337e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley K[14] = S4[x[12]] ^ S5[x[13]] ^ S6[x[3]] ^ S7[x[2]] ^ S6[x[8]]; 338e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley K[15] = S4[x[14]] ^ S5[x[15]] ^ S6[x[1]] ^ S7[x[0]] ^ S7[x[13]]; 339e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley if (K != k) { 340e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley break; 341e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 342e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley K += 16; 343e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 344e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 345e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley for (i = 0; i < 16; i++) { 346e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley key->data[i * 2] = k[i]; 347e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley key->data[i * 2 + 1] = ((k[i + 16]) + 16) & 0x1f; 348e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 349e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley} 350e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 351e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley/* The input and output encrypted as though 64bit cfb mode is being used. The 352e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * extra state information to record how much of the 64bit block we have used 353e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * is contained in *num. */ 354e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleyvoid CAST_cfb64_encrypt(const uint8_t *in, uint8_t *out, long length, 355e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley const CAST_KEY *schedule, uint8_t *ivec, int *num, 356e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley int enc) { 357e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley uint32_t v0, v1, t; 358e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley int n = *num; 359e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley long l = length; 360e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley uint32_t ti[2]; 361e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley uint8_t *iv, c, cc; 362e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 363e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley iv = ivec; 364e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley if (enc) { 365e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley while (l--) { 366e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley if (n == 0) { 367e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley n2l(iv, v0); 368e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley ti[0] = v0; 369e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley n2l(iv, v1); 370e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley ti[1] = v1; 371e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley CAST_encrypt((uint32_t *)ti, schedule); 372e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley iv = ivec; 373e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley t = ti[0]; 374e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley l2n(t, iv); 375e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley t = ti[1]; 376e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley l2n(t, iv); 377e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley iv = ivec; 378e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 379e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley c = *(in++) ^ iv[n]; 380e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley *(out++) = c; 381e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley iv[n] = c; 382e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley n = (n + 1) & 0x07; 383e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 384e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } else { 385e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley while (l--) { 386e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley if (n == 0) { 387e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley n2l(iv, v0); 388e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley ti[0] = v0; 389e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley n2l(iv, v1); 390e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley ti[1] = v1; 391e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley CAST_encrypt((uint32_t *)ti, schedule); 392e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley iv = ivec; 393e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley t = ti[0]; 394e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley l2n(t, iv); 395e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley t = ti[1]; 396e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley l2n(t, iv); 397e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley iv = ivec; 398e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 399e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley cc = *(in++); 400e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley c = iv[n]; 401e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley iv[n] = cc; 402e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley *(out++) = c ^ cc; 403e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley n = (n + 1) & 0x07; 404e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 405e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 406e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley v0 = v1 = ti[0] = ti[1] = t = c = cc = 0; 407e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley *num = n; 408e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley} 409