1/* 2 * AES-128 CBC 3 * 4 * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 * 10 * Alternatively, this software may be distributed under the terms of BSD 11 * license. 12 * 13 * See README and COPYING for more details. 14 */ 15 16#include "includes.h" 17 18#include "common.h" 19#include "aes.h" 20#include "aes_wrap.h" 21 22/** 23 * aes_128_cbc_encrypt - AES-128 CBC encryption 24 * @key: Encryption key 25 * @iv: Encryption IV for CBC mode (16 bytes) 26 * @data: Data to encrypt in-place 27 * @data_len: Length of data in bytes (must be divisible by 16) 28 * Returns: 0 on success, -1 on failure 29 */ 30int aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) 31{ 32 void *ctx; 33 u8 cbc[AES_BLOCK_SIZE]; 34 u8 *pos = data; 35 int i, j, blocks; 36 37 ctx = aes_encrypt_init(key, 16); 38 if (ctx == NULL) 39 return -1; 40 os_memcpy(cbc, iv, AES_BLOCK_SIZE); 41 42 blocks = data_len / AES_BLOCK_SIZE; 43 for (i = 0; i < blocks; i++) { 44 for (j = 0; j < AES_BLOCK_SIZE; j++) 45 cbc[j] ^= pos[j]; 46 aes_encrypt(ctx, cbc, cbc); 47 os_memcpy(pos, cbc, AES_BLOCK_SIZE); 48 pos += AES_BLOCK_SIZE; 49 } 50 aes_encrypt_deinit(ctx); 51 return 0; 52} 53 54 55/** 56 * aes_128_cbc_decrypt - AES-128 CBC decryption 57 * @key: Decryption key 58 * @iv: Decryption IV for CBC mode (16 bytes) 59 * @data: Data to decrypt in-place 60 * @data_len: Length of data in bytes (must be divisible by 16) 61 * Returns: 0 on success, -1 on failure 62 */ 63int aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) 64{ 65 void *ctx; 66 u8 cbc[AES_BLOCK_SIZE], tmp[AES_BLOCK_SIZE]; 67 u8 *pos = data; 68 int i, j, blocks; 69 70 ctx = aes_decrypt_init(key, 16); 71 if (ctx == NULL) 72 return -1; 73 os_memcpy(cbc, iv, AES_BLOCK_SIZE); 74 75 blocks = data_len / AES_BLOCK_SIZE; 76 for (i = 0; i < blocks; i++) { 77 os_memcpy(tmp, pos, AES_BLOCK_SIZE); 78 aes_decrypt(ctx, pos, pos); 79 for (j = 0; j < AES_BLOCK_SIZE; j++) 80 pos[j] ^= cbc[j]; 81 os_memcpy(cbc, tmp, AES_BLOCK_SIZE); 82 pos += AES_BLOCK_SIZE; 83 } 84 aes_decrypt_deinit(ctx); 85 return 0; 86} 87