1238384Sjkim/* ==================================================================== 2238384Sjkim * Copyright (c) 2008 The OpenSSL Project. All rights reserved. 3238384Sjkim * 4238384Sjkim * Redistribution and use in source and binary forms, with or without 5238384Sjkim * modification, are permitted provided that the following conditions 6238384Sjkim * are met: 7238384Sjkim * 8238384Sjkim * 1. Redistributions of source code must retain the above copyright 9296341Sdelphij * notice, this list of conditions and the following disclaimer. 10238384Sjkim * 11238384Sjkim * 2. Redistributions in binary form must reproduce the above copyright 12238384Sjkim * notice, this list of conditions and the following disclaimer in 13238384Sjkim * the documentation and/or other materials provided with the 14238384Sjkim * distribution. 15238384Sjkim * 16238384Sjkim * 3. All advertising materials mentioning features or use of this 17238384Sjkim * software must display the following acknowledgment: 18238384Sjkim * "This product includes software developed by the OpenSSL Project 19238384Sjkim * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 20238384Sjkim * 21238384Sjkim * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 22238384Sjkim * endorse or promote products derived from this software without 23238384Sjkim * prior written permission. For written permission, please contact 24238384Sjkim * openssl-core@openssl.org. 25238384Sjkim * 26238384Sjkim * 5. Products derived from this software may not be called "OpenSSL" 27238384Sjkim * nor may "OpenSSL" appear in their names without prior written 28238384Sjkim * permission of the OpenSSL Project. 29238384Sjkim * 30238384Sjkim * 6. Redistributions of any form whatsoever must retain the following 31238384Sjkim * acknowledgment: 32238384Sjkim * "This product includes software developed by the OpenSSL Project 33238384Sjkim * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 34238384Sjkim * 35238384Sjkim * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 36238384Sjkim * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 37238384Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 38238384Sjkim * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 39238384Sjkim * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 40238384Sjkim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 41238384Sjkim * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 42238384Sjkim * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 43238384Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 44238384Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 45238384Sjkim * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 46238384Sjkim * OF THE POSSIBILITY OF SUCH DAMAGE. 47238384Sjkim * ==================================================================== 48238384Sjkim * 49238384Sjkim */ 50238384Sjkim 51238384Sjkim#include <openssl/crypto.h> 52238384Sjkim#include "modes_lcl.h" 53238384Sjkim#include <string.h> 54238384Sjkim 55238384Sjkim#ifndef MODES_DEBUG 56238384Sjkim# ifndef NDEBUG 57238384Sjkim# define NDEBUG 58238384Sjkim# endif 59238384Sjkim#endif 60238384Sjkim#include <assert.h> 61238384Sjkim 62296341Sdelphij/* 63296341Sdelphij * NOTE: the IV/counter CTR mode is big-endian. The code itself is 64296341Sdelphij * endian-neutral. 65296341Sdelphij */ 66238384Sjkim 67238384Sjkim/* increment counter (128-bit int) by 1 */ 68296341Sdelphijstatic void ctr128_inc(unsigned char *counter) 69296341Sdelphij{ 70296341Sdelphij u32 n = 16; 71296341Sdelphij u8 c; 72238384Sjkim 73296341Sdelphij do { 74296341Sdelphij --n; 75296341Sdelphij c = counter[n]; 76296341Sdelphij ++c; 77296341Sdelphij counter[n] = c; 78296341Sdelphij if (c) 79296341Sdelphij return; 80296341Sdelphij } while (n); 81238384Sjkim} 82238384Sjkim 83238384Sjkim#if !defined(OPENSSL_SMALL_FOOTPRINT) 84296341Sdelphijstatic void ctr128_inc_aligned(unsigned char *counter) 85296341Sdelphij{ 86296341Sdelphij size_t *data, c, n; 87296341Sdelphij const union { 88296341Sdelphij long one; 89296341Sdelphij char little; 90296341Sdelphij } is_endian = { 91296341Sdelphij 1 92296341Sdelphij }; 93238384Sjkim 94296341Sdelphij if (is_endian.little) { 95296341Sdelphij ctr128_inc(counter); 96296341Sdelphij return; 97296341Sdelphij } 98238384Sjkim 99296341Sdelphij data = (size_t *)counter; 100296341Sdelphij n = 16 / sizeof(size_t); 101296341Sdelphij do { 102296341Sdelphij --n; 103296341Sdelphij c = data[n]; 104296341Sdelphij ++c; 105296341Sdelphij data[n] = c; 106296341Sdelphij if (c) 107296341Sdelphij return; 108296341Sdelphij } while (n); 109238384Sjkim} 110238384Sjkim#endif 111238384Sjkim 112296341Sdelphij/* 113296341Sdelphij * The input encrypted as though 128bit counter mode is being used. The 114296341Sdelphij * extra state information to record how much of the 128bit block we have 115296341Sdelphij * used is contained in *num, and the encrypted counter is kept in 116296341Sdelphij * ecount_buf. Both *num and ecount_buf must be initialised with zeros 117296341Sdelphij * before the first call to CRYPTO_ctr128_encrypt(). This algorithm assumes 118296341Sdelphij * that the counter is in the x lower bits of the IV (ivec), and that the 119296341Sdelphij * application has full control over overflow and the rest of the IV. This 120296341Sdelphij * implementation takes NO responsability for checking that the counter 121296341Sdelphij * doesn't overflow into the rest of the IV when incremented. 122238384Sjkim */ 123238384Sjkimvoid CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out, 124296341Sdelphij size_t len, const void *key, 125296341Sdelphij unsigned char ivec[16], 126296341Sdelphij unsigned char ecount_buf[16], unsigned int *num, 127296341Sdelphij block128_f block) 128238384Sjkim{ 129296341Sdelphij unsigned int n; 130296341Sdelphij size_t l = 0; 131238384Sjkim 132296341Sdelphij assert(in && out && key && ecount_buf && num); 133296341Sdelphij assert(*num < 16); 134238384Sjkim 135296341Sdelphij n = *num; 136238384Sjkim 137238384Sjkim#if !defined(OPENSSL_SMALL_FOOTPRINT) 138296341Sdelphij if (16 % sizeof(size_t) == 0) { /* always true actually */ 139296341Sdelphij do { 140296341Sdelphij while (n && len) { 141296341Sdelphij *(out++) = *(in++) ^ ecount_buf[n]; 142296341Sdelphij --len; 143296341Sdelphij n = (n + 1) % 16; 144296341Sdelphij } 145238384Sjkim 146296341Sdelphij# if defined(STRICT_ALIGNMENT) 147296341Sdelphij if (((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 148296341Sdelphij 0) 149296341Sdelphij break; 150296341Sdelphij# endif 151296341Sdelphij while (len >= 16) { 152296341Sdelphij (*block) (ivec, ecount_buf, key); 153296341Sdelphij ctr128_inc_aligned(ivec); 154296341Sdelphij for (; n < 16; n += sizeof(size_t)) 155296341Sdelphij *(size_t *)(out + n) = 156296341Sdelphij *(size_t *)(in + n) ^ *(size_t *)(ecount_buf + n); 157296341Sdelphij len -= 16; 158296341Sdelphij out += 16; 159296341Sdelphij in += 16; 160296341Sdelphij n = 0; 161296341Sdelphij } 162296341Sdelphij if (len) { 163296341Sdelphij (*block) (ivec, ecount_buf, key); 164296341Sdelphij ctr128_inc_aligned(ivec); 165296341Sdelphij while (len--) { 166296341Sdelphij out[n] = in[n] ^ ecount_buf[n]; 167296341Sdelphij ++n; 168296341Sdelphij } 169296341Sdelphij } 170296341Sdelphij *num = n; 171296341Sdelphij return; 172296341Sdelphij } while (0); 173296341Sdelphij } 174296341Sdelphij /* the rest would be commonly eliminated by x86* compiler */ 175238384Sjkim#endif 176296341Sdelphij while (l < len) { 177296341Sdelphij if (n == 0) { 178296341Sdelphij (*block) (ivec, ecount_buf, key); 179296341Sdelphij ctr128_inc(ivec); 180296341Sdelphij } 181296341Sdelphij out[l] = in[l] ^ ecount_buf[n]; 182296341Sdelphij ++l; 183296341Sdelphij n = (n + 1) % 16; 184296341Sdelphij } 185238384Sjkim 186296341Sdelphij *num = n; 187238384Sjkim} 188238384Sjkim 189238384Sjkim/* increment upper 96 bits of 128-bit counter by 1 */ 190296341Sdelphijstatic void ctr96_inc(unsigned char *counter) 191296341Sdelphij{ 192296341Sdelphij u32 n = 12; 193296341Sdelphij u8 c; 194238384Sjkim 195296341Sdelphij do { 196296341Sdelphij --n; 197296341Sdelphij c = counter[n]; 198296341Sdelphij ++c; 199296341Sdelphij counter[n] = c; 200296341Sdelphij if (c) 201296341Sdelphij return; 202296341Sdelphij } while (n); 203238384Sjkim} 204238384Sjkim 205238384Sjkimvoid CRYPTO_ctr128_encrypt_ctr32(const unsigned char *in, unsigned char *out, 206296341Sdelphij size_t len, const void *key, 207296341Sdelphij unsigned char ivec[16], 208296341Sdelphij unsigned char ecount_buf[16], 209296341Sdelphij unsigned int *num, ctr128_f func) 210238384Sjkim{ 211296341Sdelphij unsigned int n, ctr32; 212238384Sjkim 213296341Sdelphij assert(in && out && key && ecount_buf && num); 214296341Sdelphij assert(*num < 16); 215238384Sjkim 216296341Sdelphij n = *num; 217238384Sjkim 218296341Sdelphij while (n && len) { 219296341Sdelphij *(out++) = *(in++) ^ ecount_buf[n]; 220296341Sdelphij --len; 221296341Sdelphij n = (n + 1) % 16; 222296341Sdelphij } 223238384Sjkim 224296341Sdelphij ctr32 = GETU32(ivec + 12); 225296341Sdelphij while (len >= 16) { 226296341Sdelphij size_t blocks = len / 16; 227296341Sdelphij /* 228296341Sdelphij * 1<<28 is just a not-so-small yet not-so-large number... 229296341Sdelphij * Below condition is practically never met, but it has to 230296341Sdelphij * be checked for code correctness. 231296341Sdelphij */ 232296341Sdelphij if (sizeof(size_t) > sizeof(unsigned int) && blocks > (1U << 28)) 233296341Sdelphij blocks = (1U << 28); 234296341Sdelphij /* 235296341Sdelphij * As (*func) operates on 32-bit counter, caller 236296341Sdelphij * has to handle overflow. 'if' below detects the 237296341Sdelphij * overflow, which is then handled by limiting the 238296341Sdelphij * amount of blocks to the exact overflow point... 239296341Sdelphij */ 240296341Sdelphij ctr32 += (u32)blocks; 241296341Sdelphij if (ctr32 < blocks) { 242296341Sdelphij blocks -= ctr32; 243296341Sdelphij ctr32 = 0; 244296341Sdelphij } 245296341Sdelphij (*func) (in, out, blocks, key, ivec); 246296341Sdelphij /* (*ctr) does not update ivec, caller does: */ 247296341Sdelphij PUTU32(ivec + 12, ctr32); 248296341Sdelphij /* ... overflow was detected, propogate carry. */ 249296341Sdelphij if (ctr32 == 0) 250296341Sdelphij ctr96_inc(ivec); 251296341Sdelphij blocks *= 16; 252296341Sdelphij len -= blocks; 253296341Sdelphij out += blocks; 254296341Sdelphij in += blocks; 255296341Sdelphij } 256296341Sdelphij if (len) { 257296341Sdelphij memset(ecount_buf, 0, 16); 258296341Sdelphij (*func) (ecount_buf, ecount_buf, 1, key, ivec); 259296341Sdelphij ++ctr32; 260296341Sdelphij PUTU32(ivec + 12, ctr32); 261296341Sdelphij if (ctr32 == 0) 262296341Sdelphij ctr96_inc(ivec); 263296341Sdelphij while (len--) { 264296341Sdelphij out[n] = in[n] ^ ecount_buf[n]; 265296341Sdelphij ++n; 266296341Sdelphij } 267296341Sdelphij } 268238384Sjkim 269296341Sdelphij *num = n; 270238384Sjkim} 271