1295367Sdes/* $OpenBSD: cipher-aesctr.c,v 1.2 2015/01/14 10:24:42 markus Exp $ */ 2276707Sdes/* 3295367Sdes * Copyright (c) 2003 Markus Friedl. All rights reserved. 4276707Sdes * 5276707Sdes * Permission to use, copy, modify, and distribute this software for any 6276707Sdes * purpose with or without fee is hereby granted, provided that the above 7276707Sdes * copyright notice and this permission notice appear in all copies. 8276707Sdes * 9276707Sdes * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10276707Sdes * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11276707Sdes * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12276707Sdes * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13276707Sdes * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14276707Sdes * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15276707Sdes * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16276707Sdes */ 17276707Sdes 18295367Sdes#include "includes.h" 19295367Sdes 20276707Sdes#include <sys/types.h> 21276707Sdes#include <string.h> 22276707Sdes 23295367Sdes#ifndef WITH_OPENSSL 24295367Sdes 25276707Sdes#include "cipher-aesctr.h" 26276707Sdes 27276707Sdes/* 28276707Sdes * increment counter 'ctr', 29276707Sdes * the counter is of size 'len' bytes and stored in network-byte-order. 30276707Sdes * (LSB at ctr[len-1], MSB at ctr[0]) 31276707Sdes */ 32295367Sdesstatic inline void 33276707Sdesaesctr_inc(u8 *ctr, u32 len) 34276707Sdes{ 35276707Sdes ssize_t i; 36276707Sdes 37276707Sdes#ifndef CONSTANT_TIME_INCREMENT 38276707Sdes for (i = len - 1; i >= 0; i--) 39276707Sdes if (++ctr[i]) /* continue on overflow */ 40276707Sdes return; 41276707Sdes#else 42276707Sdes u8 x, add = 1; 43276707Sdes 44276707Sdes for (i = len - 1; i >= 0; i--) { 45276707Sdes ctr[i] += add; 46276707Sdes /* constant time for: x = ctr[i] ? 1 : 0 */ 47276707Sdes x = ctr[i]; 48276707Sdes x = (x | (x >> 4)) & 0xf; 49276707Sdes x = (x | (x >> 2)) & 0x3; 50276707Sdes x = (x | (x >> 1)) & 0x1; 51276707Sdes add *= (x^1); 52276707Sdes } 53276707Sdes#endif 54276707Sdes} 55276707Sdes 56276707Sdesvoid 57276707Sdesaesctr_keysetup(aesctr_ctx *x,const u8 *k,u32 kbits,u32 ivbits) 58276707Sdes{ 59276707Sdes x->rounds = rijndaelKeySetupEnc(x->ek, k, kbits); 60276707Sdes} 61276707Sdes 62276707Sdesvoid 63276707Sdesaesctr_ivsetup(aesctr_ctx *x,const u8 *iv) 64276707Sdes{ 65276707Sdes memcpy(x->ctr, iv, AES_BLOCK_SIZE); 66276707Sdes} 67276707Sdes 68276707Sdesvoid 69276707Sdesaesctr_encrypt_bytes(aesctr_ctx *x,const u8 *m,u8 *c,u32 bytes) 70276707Sdes{ 71276707Sdes u32 n = 0; 72276707Sdes u8 buf[AES_BLOCK_SIZE]; 73276707Sdes 74276707Sdes while ((bytes--) > 0) { 75276707Sdes if (n == 0) { 76276707Sdes rijndaelEncrypt(x->ek, x->rounds, x->ctr, buf); 77276707Sdes aesctr_inc(x->ctr, AES_BLOCK_SIZE); 78276707Sdes } 79276707Sdes *(c++) = *(m++) ^ buf[n]; 80276707Sdes n = (n + 1) % AES_BLOCK_SIZE; 81276707Sdes } 82276707Sdes} 83295367Sdes#endif /* !WITH_OPENSSL */ 84