1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* ==================================================================== 2221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * Copyright (c) 2008 The OpenSSL Project. All rights reserved. 3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Redistribution and use in source and binary forms, with or without 5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * modification, are permitted provided that the following conditions 6656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * are met: 7656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 1. Redistributions of source code must retain the above copyright 9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * notice, this list of conditions and the following disclaimer. 10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * notice, this list of conditions and the following disclaimer in 13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the documentation and/or other materials provided with the 14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * distribution. 15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 3. All advertising materials mentioning features or use of this 17656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * software must display the following acknowledgment: 18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * "This product includes software developed by the OpenSSL Project 19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * endorse or promote products derived from this software without 23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * prior written permission. For written permission, please contact 24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * openssl-core@openssl.org. 25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 5. Products derived from this software may not be called "OpenSSL" 27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * nor may "OpenSSL" appear in their names without prior written 28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * permission of the OpenSSL Project. 29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 6. Redistributions of any form whatsoever must retain the following 31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * acknowledgment: 32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * "This product includes software developed by the OpenSSL Project 33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 35656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OF THE POSSIBILITY OF SUCH DAMAGE. 47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ==================================================================== 48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 51392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#include <openssl/crypto.h> 52392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#include "modes_lcl.h" 53221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#include <string.h> 54221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 55221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#ifndef MODES_DEBUG 56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project# ifndef NDEBUG 57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project# define NDEBUG 58656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project# endif 59656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif 60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <assert.h> 61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 62221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/* NOTE: the IV/counter CTR mode is big-endian. The code itself 63221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * is endian-neutral. */ 64656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 65221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/* increment counter (128-bit int) by 1 */ 66221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic void ctr128_inc(unsigned char *counter) { 673d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom u32 n=16; 683d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom u8 c; 69221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 70221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom do { 713d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom --n; 723d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom c = counter[n]; 733d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom ++c; 743d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom counter[n] = c; 75221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (c) return; 76221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } while (n); 77221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom} 78221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 793d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom#if !defined(OPENSSL_SMALL_FOOTPRINT) 80221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic void ctr128_inc_aligned(unsigned char *counter) { 81221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom size_t *data,c,n; 82221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom const union { long one; char little; } is_endian = {1}; 83221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 84221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (is_endian.little) { 85221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom ctr128_inc(counter); 86656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return; 87656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 88656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 89221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom data = (size_t *)counter; 90221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom n = 16/sizeof(size_t); 91221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom do { 92221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom --n; 93221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom c = data[n]; 94221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom ++c; 95221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom data[n] = c; 96221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (c) return; 97221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } while (n); 98221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom} 99221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#endif 100221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* The input encrypted as though 128bit counter mode is being 102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * used. The extra state information to record how much of the 103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 128bit block we have used is contained in *num, and the 104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * encrypted counter is kept in ecount_buf. Both *num and 105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ecount_buf must be initialised with zeros before the first 106221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * call to CRYPTO_ctr128_encrypt(). 107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 108656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This algorithm assumes that the counter is in the x lower bits 109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * of the IV (ivec), and that the application has full control over 110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * overflow and the rest of the IV. This implementation takes NO 111656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * responsability for checking that the counter doesn't overflow 112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * into the rest of the IV when incremented. 113656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 114221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromvoid CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out, 115221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom size_t len, const void *key, 116221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom unsigned char ivec[16], unsigned char ecount_buf[16], 117221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom unsigned int *num, block128_f block) 118221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ 119656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned int n; 120221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom size_t l=0; 121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 122221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom assert(in && out && key && ecount_buf && num); 123221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom assert(*num < 16); 124656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 125656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project n = *num; 126656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 127221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#if !defined(OPENSSL_SMALL_FOOTPRINT) 128221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (16%sizeof(size_t) == 0) do { /* always true actually */ 129221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom while (n && len) { 130221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *(out++) = *(in++) ^ ecount_buf[n]; 131221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom --len; 132221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom n = (n+1) % 16; 133656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 134656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 135221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#if defined(STRICT_ALIGNMENT) 136221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) 137221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom break; 138221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#endif 139221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom while (len>=16) { 140221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom (*block)(ivec, ecount_buf, key); 141221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom ctr128_inc_aligned(ivec); 1423d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom for (; n<16; n+=sizeof(size_t)) 143221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *(size_t *)(out+n) = 144221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *(size_t *)(in+n) ^ *(size_t *)(ecount_buf+n); 145221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom len -= 16; 146221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom out += 16; 147221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom in += 16; 1483d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom n = 0; 149221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 150221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (len) { 151221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom (*block)(ivec, ecount_buf, key); 152221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom ctr128_inc_aligned(ivec); 153221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom while (len--) { 154221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom out[n] = in[n] ^ ecount_buf[n]; 155221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom ++n; 156221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 157221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 158221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *num = n; 159221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return; 160221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } while(0); 161221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom /* the rest would be commonly eliminated by x86* compiler */ 162221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#endif 163221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom while (l<len) { 164221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (n==0) { 165221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom (*block)(ivec, ecount_buf, key); 166221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom ctr128_inc(ivec); 167221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 168221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom out[l] = in[l] ^ ecount_buf[n]; 169221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom ++l; 170221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom n = (n+1) % 16; 171656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 172656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 173221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *num=n; 174221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom} 175392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 176392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom/* increment upper 96 bits of 128-bit counter by 1 */ 177392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic void ctr96_inc(unsigned char *counter) { 178392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom u32 n=12; 179392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom u8 c; 180392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 181392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom do { 182392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom --n; 183392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom c = counter[n]; 184392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ++c; 185392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom counter[n] = c; 186392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (c) return; 187392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } while (n); 188392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom} 189392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 190392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromvoid CRYPTO_ctr128_encrypt_ctr32(const unsigned char *in, unsigned char *out, 191392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom size_t len, const void *key, 192392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom unsigned char ivec[16], unsigned char ecount_buf[16], 193392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom unsigned int *num, ctr128_f func) 194392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom{ 195392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom unsigned int n,ctr32; 196392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 197392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom assert(in && out && key && ecount_buf && num); 198392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom assert(*num < 16); 199392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 200392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom n = *num; 201392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 202392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom while (n && len) { 203392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom *(out++) = *(in++) ^ ecount_buf[n]; 204392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom --len; 205392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom n = (n+1) % 16; 206392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 207392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 208392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctr32 = GETU32(ivec+12); 209392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom while (len>=16) { 210392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom size_t blocks = len/16; 211392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom /* 212392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 1<<28 is just a not-so-small yet not-so-large number... 213392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * Below condition is practically never met, but it has to 214392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * be checked for code correctness. 215392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom */ 216392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (sizeof(size_t)>sizeof(unsigned int) && blocks>(1U<<28)) 217392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom blocks = (1U<<28); 218392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom /* 219392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * As (*func) operates on 32-bit counter, caller 220392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * has to handle overflow. 'if' below detects the 221392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * overflow, which is then handled by limiting the 222392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * amount of blocks to the exact overflow point... 223392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom */ 224392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctr32 += (u32)blocks; 225392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (ctr32 < blocks) { 226392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom blocks -= ctr32; 227392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctr32 = 0; 228392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 229392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom (*func)(in,out,blocks,key,ivec); 230392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom /* (*ctr) does not update ivec, caller does: */ 231392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom PUTU32(ivec+12,ctr32); 232392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom /* ... overflow was detected, propogate carry. */ 233392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (ctr32 == 0) ctr96_inc(ivec); 234392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom blocks *= 16; 235392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom len -= blocks; 236392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom out += blocks; 237392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom in += blocks; 238392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 239392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (len) { 240392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom memset(ecount_buf,0,16); 241392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom (*func)(ecount_buf,ecount_buf,1,key,ivec); 242392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ++ctr32; 243392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom PUTU32(ivec+12,ctr32); 244392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (ctr32 == 0) ctr96_inc(ivec); 245392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom while (len--) { 246392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom out[n] = in[n] ^ ecount_buf[n]; 247392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ++n; 248392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 249392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 250392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 251392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom *num=n; 252392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom} 253