aes.c revision 1.1
1/* $NetBSD: aes.c,v 1.1 2011/04/13 18:14:49 elric Exp $ */ 2 3/* 4 * Copyright (c) 2003 Kungliga Tekniska H��gskolan 5 * (Royal Institute of Technology, Stockholm, Sweden). 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * 3. Neither the name of the Institute nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36#include "config.h" 37 38 39#ifdef KRB5 40#include <krb5/krb5-types.h> 41#endif 42 43#include <string.h> 44 45#include "rijndael-alg-fst.h" 46#include "aes.h" 47 48int 49AES_set_encrypt_key(const unsigned char *userkey, const int bits, AES_KEY *key) 50{ 51 key->rounds = rijndaelKeySetupEnc(key->key, userkey, bits); 52 if (key->rounds == 0) 53 return -1; 54 return 0; 55} 56 57int 58AES_set_decrypt_key(const unsigned char *userkey, const int bits, AES_KEY *key) 59{ 60 key->rounds = rijndaelKeySetupDec(key->key, userkey, bits); 61 if (key->rounds == 0) 62 return -1; 63 return 0; 64} 65 66void 67AES_encrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key) 68{ 69 rijndaelEncrypt(key->key, key->rounds, in, out); 70} 71 72void 73AES_decrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key) 74{ 75 rijndaelDecrypt(key->key, key->rounds, in, out); 76} 77 78void 79AES_cbc_encrypt(const unsigned char *in, unsigned char *out, 80 unsigned long size, const AES_KEY *key, 81 unsigned char *iv, int forward_encrypt) 82{ 83 unsigned char tmp[AES_BLOCK_SIZE]; 84 int i; 85 86 if (forward_encrypt) { 87 while (size >= AES_BLOCK_SIZE) { 88 for (i = 0; i < AES_BLOCK_SIZE; i++) 89 tmp[i] = in[i] ^ iv[i]; 90 AES_encrypt(tmp, out, key); 91 memcpy(iv, out, AES_BLOCK_SIZE); 92 size -= AES_BLOCK_SIZE; 93 in += AES_BLOCK_SIZE; 94 out += AES_BLOCK_SIZE; 95 } 96 if (size) { 97 for (i = 0; i < size; i++) 98 tmp[i] = in[i] ^ iv[i]; 99 for (i = size; i < AES_BLOCK_SIZE; i++) 100 tmp[i] = iv[i]; 101 AES_encrypt(tmp, out, key); 102 memcpy(iv, out, AES_BLOCK_SIZE); 103 } 104 } else { 105 while (size >= AES_BLOCK_SIZE) { 106 memcpy(tmp, in, AES_BLOCK_SIZE); 107 AES_decrypt(tmp, out, key); 108 for (i = 0; i < AES_BLOCK_SIZE; i++) 109 out[i] ^= iv[i]; 110 memcpy(iv, tmp, AES_BLOCK_SIZE); 111 size -= AES_BLOCK_SIZE; 112 in += AES_BLOCK_SIZE; 113 out += AES_BLOCK_SIZE; 114 } 115 if (size) { 116 memcpy(tmp, in, AES_BLOCK_SIZE); 117 AES_decrypt(tmp, out, key); 118 for (i = 0; i < size; i++) 119 out[i] ^= iv[i]; 120 memcpy(iv, tmp, AES_BLOCK_SIZE); 121 } 122 } 123} 124 125void 126AES_cfb8_encrypt(const unsigned char *in, unsigned char *out, 127 unsigned long size, const AES_KEY *key, 128 unsigned char *iv, int forward_encrypt) 129{ 130 int i; 131 132 for (i = 0; i < size; i++) { 133 unsigned char tmp[AES_BLOCK_SIZE + 1]; 134 135 memcpy(tmp, iv, AES_BLOCK_SIZE); 136 AES_encrypt(iv, iv, key); 137 if (!forward_encrypt) { 138 tmp[AES_BLOCK_SIZE] = in[i]; 139 } 140 out[i] = in[i] ^ iv[0]; 141 if (forward_encrypt) { 142 tmp[AES_BLOCK_SIZE] = out[i]; 143 } 144 memcpy(iv, &tmp[1], AES_BLOCK_SIZE); 145 } 146} 147