hostap/src/crypto/aes-cbc.c
Jouni Malinen 1ba787b954 Remove unneeded aes_i.h inclusion from number of places
The BLOCK_SIZE define can be made more specific by using AES_ prefix and
by moving it to aes.h. After this, most aes-*.c do not really need to
include anything from the internal aes_i.h header file. In other words,
aes_i.h can now be used only for the code that uses the internal AES
block operation implementation and none of the code that can use AES
implementation from an external library do not need to include this
header file.
2009-08-17 20:27:25 +03:00

85 lines
2.1 KiB
C

/*
* AES-128 CBC
*
* Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Alternatively, this software may be distributed under the terms of BSD
* license.
*
* See README and COPYING for more details.
*/
#include "includes.h"
#include "common.h"
#include "aes.h"
/**
* aes_128_cbc_encrypt - AES-128 CBC encryption
* @key: Encryption key
* @iv: Encryption IV for CBC mode (16 bytes)
* @data: Data to encrypt in-place
* @data_len: Length of data in bytes (must be divisible by 16)
* Returns: 0 on success, -1 on failure
*/
int aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
{
void *ctx;
u8 cbc[AES_BLOCK_SIZE];
u8 *pos = data;
int i, j, blocks;
ctx = aes_encrypt_init(key, 16);
if (ctx == NULL)
return -1;
os_memcpy(cbc, iv, AES_BLOCK_SIZE);
blocks = data_len / AES_BLOCK_SIZE;
for (i = 0; i < blocks; i++) {
for (j = 0; j < AES_BLOCK_SIZE; j++)
cbc[j] ^= pos[j];
aes_encrypt(ctx, cbc, cbc);
os_memcpy(pos, cbc, AES_BLOCK_SIZE);
pos += AES_BLOCK_SIZE;
}
aes_encrypt_deinit(ctx);
return 0;
}
/**
* aes_128_cbc_decrypt - AES-128 CBC decryption
* @key: Decryption key
* @iv: Decryption IV for CBC mode (16 bytes)
* @data: Data to decrypt in-place
* @data_len: Length of data in bytes (must be divisible by 16)
* Returns: 0 on success, -1 on failure
*/
int aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
{
void *ctx;
u8 cbc[AES_BLOCK_SIZE], tmp[AES_BLOCK_SIZE];
u8 *pos = data;
int i, j, blocks;
ctx = aes_decrypt_init(key, 16);
if (ctx == NULL)
return -1;
os_memcpy(cbc, iv, AES_BLOCK_SIZE);
blocks = data_len / AES_BLOCK_SIZE;
for (i = 0; i < blocks; i++) {
os_memcpy(tmp, pos, AES_BLOCK_SIZE);
aes_decrypt(ctx, pos, pos);
for (j = 0; j < AES_BLOCK_SIZE; j++)
pos[j] ^= cbc[j];
os_memcpy(cbc, tmp, AES_BLOCK_SIZE);
pos += AES_BLOCK_SIZE;
}
aes_decrypt_deinit(ctx);
return 0;
}