1221420Sdes/* $OpenBSD: cipher-ctr.c,v 1.11 2010/10/01 23:05:32 djm Exp $ */ 2124208Sdes/* 3124208Sdes * Copyright (c) 2003 Markus Friedl <markus@openbsd.org> 4124208Sdes * 5124208Sdes * Permission to use, copy, modify, and distribute this software for any 6124208Sdes * purpose with or without fee is hereby granted, provided that the above 7124208Sdes * copyright notice and this permission notice appear in all copies. 8124208Sdes * 9124208Sdes * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10124208Sdes * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11124208Sdes * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12124208Sdes * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13124208Sdes * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14124208Sdes * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15124208Sdes * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16124208Sdes */ 17124208Sdes#include "includes.h" 18124208Sdes 19295367Sdes#if defined(WITH_OPENSSL) && !defined(OPENSSL_HAVE_EVPCTR) 20162852Sdes#include <sys/types.h> 21162852Sdes 22162852Sdes#include <stdarg.h> 23162852Sdes#include <string.h> 24162852Sdes 25124208Sdes#include <openssl/evp.h> 26124208Sdes 27162852Sdes#include "xmalloc.h" 28124208Sdes#include "log.h" 29124208Sdes 30157016Sdes/* compatibility with old or broken OpenSSL versions */ 31157016Sdes#include "openbsd-compat/openssl-compat.h" 32124208Sdes 33181111Sdes#ifndef USE_BUILTIN_RIJNDAEL 34124208Sdes#include <openssl/aes.h> 35124208Sdes#endif 36124208Sdes 37124208Sdesstruct ssh_aes_ctr_ctx 38124208Sdes{ 39124208Sdes AES_KEY aes_ctx; 40124208Sdes u_char aes_counter[AES_BLOCK_SIZE]; 41124208Sdes}; 42124208Sdes 43124208Sdes/* 44124208Sdes * increment counter 'ctr', 45124208Sdes * the counter is of size 'len' bytes and stored in network-byte-order. 46124208Sdes * (LSB at ctr[len-1], MSB at ctr[0]) 47124208Sdes */ 48124208Sdesstatic void 49221420Sdesssh_ctr_inc(u_char *ctr, size_t len) 50124208Sdes{ 51124208Sdes int i; 52124208Sdes 53124208Sdes for (i = len - 1; i >= 0; i--) 54124208Sdes if (++ctr[i]) /* continue on overflow */ 55124208Sdes return; 56124208Sdes} 57124208Sdes 58124208Sdesstatic int 59124208Sdesssh_aes_ctr(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, 60221420Sdes LIBCRYPTO_EVP_INL_TYPE len) 61124208Sdes{ 62124208Sdes struct ssh_aes_ctr_ctx *c; 63221420Sdes size_t n = 0; 64124208Sdes u_char buf[AES_BLOCK_SIZE]; 65124208Sdes 66124208Sdes if (len == 0) 67124208Sdes return (1); 68124208Sdes if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) 69124208Sdes return (0); 70124208Sdes 71124208Sdes while ((len--) > 0) { 72124208Sdes if (n == 0) { 73124208Sdes AES_encrypt(c->aes_counter, buf, &c->aes_ctx); 74124208Sdes ssh_ctr_inc(c->aes_counter, AES_BLOCK_SIZE); 75124208Sdes } 76124208Sdes *(dest++) = *(src++) ^ buf[n]; 77124208Sdes n = (n + 1) % AES_BLOCK_SIZE; 78124208Sdes } 79124208Sdes return (1); 80124208Sdes} 81124208Sdes 82124208Sdesstatic int 83124208Sdesssh_aes_ctr_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv, 84124208Sdes int enc) 85124208Sdes{ 86124208Sdes struct ssh_aes_ctr_ctx *c; 87124208Sdes 88124208Sdes if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) { 89124208Sdes c = xmalloc(sizeof(*c)); 90124208Sdes EVP_CIPHER_CTX_set_app_data(ctx, c); 91124208Sdes } 92124208Sdes if (key != NULL) 93126274Sdes AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, 94149749Sdes &c->aes_ctx); 95124208Sdes if (iv != NULL) 96124208Sdes memcpy(c->aes_counter, iv, AES_BLOCK_SIZE); 97124208Sdes return (1); 98124208Sdes} 99124208Sdes 100124208Sdesstatic int 101124208Sdesssh_aes_ctr_cleanup(EVP_CIPHER_CTX *ctx) 102124208Sdes{ 103124208Sdes struct ssh_aes_ctr_ctx *c; 104124208Sdes 105124208Sdes if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) { 106124208Sdes memset(c, 0, sizeof(*c)); 107255767Sdes free(c); 108124208Sdes EVP_CIPHER_CTX_set_app_data(ctx, NULL); 109124208Sdes } 110124208Sdes return (1); 111124208Sdes} 112124208Sdes 113124208Sdesvoid 114221420Sdesssh_aes_ctr_iv(EVP_CIPHER_CTX *evp, int doset, u_char * iv, size_t len) 115124208Sdes{ 116124208Sdes struct ssh_aes_ctr_ctx *c; 117124208Sdes 118124208Sdes if ((c = EVP_CIPHER_CTX_get_app_data(evp)) == NULL) 119124208Sdes fatal("ssh_aes_ctr_iv: no context"); 120124208Sdes if (doset) 121124208Sdes memcpy(c->aes_counter, iv, len); 122124208Sdes else 123124208Sdes memcpy(iv, c->aes_counter, len); 124124208Sdes} 125124208Sdes 126124208Sdesconst EVP_CIPHER * 127124208Sdesevp_aes_128_ctr(void) 128124208Sdes{ 129124208Sdes static EVP_CIPHER aes_ctr; 130124208Sdes 131124208Sdes memset(&aes_ctr, 0, sizeof(EVP_CIPHER)); 132124208Sdes aes_ctr.nid = NID_undef; 133124208Sdes aes_ctr.block_size = AES_BLOCK_SIZE; 134124208Sdes aes_ctr.iv_len = AES_BLOCK_SIZE; 135124208Sdes aes_ctr.key_len = 16; 136124208Sdes aes_ctr.init = ssh_aes_ctr_init; 137124208Sdes aes_ctr.cleanup = ssh_aes_ctr_cleanup; 138124208Sdes aes_ctr.do_cipher = ssh_aes_ctr; 139124208Sdes#ifndef SSH_OLD_EVP 140124208Sdes aes_ctr.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | 141124208Sdes EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV; 142124208Sdes#endif 143124208Sdes return (&aes_ctr); 144124208Sdes} 145248619Sdes 146295367Sdes#endif /* defined(WITH_OPENSSL) && !defined(OPENSSL_HAVE_EVPCTR) */ 147