📄 aes_cbc.c
字号:
/* * aes_cbc.c * * AES Cipher Block Chaining Mode * * David A. McGrew * Cisco Systems, Inc. *//* * * Copyright (c) 2001-2004, Cisco Systems, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Cisco Systems, Inc. nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * */#define ALIGN_32 0#include "aes_cbc.h"#include "alloc.h"debug_module_t mod_aes_cbc = { 0, /* debugging is off by default */ "aes cbc" /* printable module name */};/* * aes_cbc_set_key(...) initializes the aes_cbc_ctx_t * using the value in key[]. * * the key is the secret key * * the salt is unpredictable (but not necessarily secret) data which * randomizes the starting point in the keystream */err_status_taes_cbc_set_key(aes_cbc_ctx_t *c, const unsigned char *key) { v128_t tmp_key; /* set tmp_key (for alignment) */ v128_copy_octet_string(&tmp_key, key); debug_print(mod_aes_cbc, "key: %s", v128_hex_string(tmp_key)); /* expand key */ aes_expand_encryption_key(tmp_key, c->expanded_key); return err_status_ok;}err_status_taes_cbc_encrypt(aes_cbc_ctx_t *c, const unsigned char *iv, unsigned char *data, unsigned int *bytes_in_data) { int i; v128_t state; unsigned char *input = data; /* pointer to data being read */ unsigned char *output = data; /* pointer to data being written */ int bytes_to_encr = *bytes_in_data; debug_print(mod_aes_cbc, "iv: %d", octet_string_hex_string(iv, 16)); /* set state to iv */ for (i=0; i < 16; i++) state.octet[i] = iv[i]; /* * loop over plaintext blocks, exoring state into plaintext then * encrypting and writing to output */ while (bytes_to_encr > 16) { /* exor plaintext into state */ for (i=0; i < 16; i++) state.octet[i] ^= *input++; aes_encrypt(c->expanded_key, &state); /* copy ciphertext to output */ for (i=0; i < 16; i++) *output++ = state.octet[i]; bytes_to_encr -= 16; } /* * handle final block - set as many plaintext bytes as needed, then * pad out the final block as specified in RFC2406, encrypt, and write * to output */ for (i=0; i < bytes_to_encr; i++) { state.octet[i] ^= *input++; } for ( ; i < 16; i++) { octet_t j = 1; state.octet[i] ^= j++; } aes_encrypt(c->expanded_key, &state); for (i=0; i < 16; i++) *output++ = state.octet[i]; /* increment data size */ *bytes_in_data += (16 - bytes_to_encr); return err_status_ok;}err_status_taes_cbc_decrypt(aes_cbc_ctx_t *c, const unsigned char *iv, unsigned char *data, unsigned int *bytes_in_data) { int i; v128_t state, ciphertext, previous; unsigned char *input = data; /* pointer to data being read */ unsigned char *output = data; /* pointer to data being written */ int bytes_to_encr = *bytes_in_data; debug_print(mod_aes_cbc, "iv: %d", octet_string_hex_string(iv, 16)); /* set previous to iv */ for (i=0; i < 16; i++) previous.octet[i] = iv[i]; /* * loop over ciphertext blocks, decrypting then exoring with state * then writing plaintext to output */ while (bytes_to_encr > 16) { /* set state and ciphertext */ for (i=0; i < 16; i++) ciphertext.octet[i] = state.octet[i] = *input++; /* decrypt state */ aes_decrypt(c->expanded_key, &state); /* * exor previous ciphertext block out of plaintext, and write * plaintext to output (while copying ciphertext to previous) */ for (i=0; i < 16; i++) { *output++ = state.octet[i] ^ previous.octet[i]; previous.octet[i] = ciphertext.octet[i]; } bytes_to_encr -= 16; } /* * handle final block - decrypt, copy the needed number of plaintext * bytes, then check the final block as specified in RFC2406 */ for (i=0; i < bytes_to_encr; i++) { state.octet[i] ^= *input++; } for ( ; i < 16; i++) { octet_t j = 1; state.octet[i] ^= j++; } aes_encrypt(c->expanded_key, &state); for (i=0; i < 16; i++) *output++ = state.octet[i]; /* increment data size */ *bytes_in_data += (16 - bytes_to_encr); return err_status_ok;}char aes_cbc_description[] = "aes cipher block chaining mode";octet_t aes_cbc_test_case_0_key[30] = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd};octet_t aes_cbc_test_case_0_plaintext[32] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };octet_t aes_cbc_test_case_0_ciphertext[32] = { 0xe0, 0x3e, 0xad, 0x09, 0x35, 0xc9, 0x5e, 0x80, 0xe1, 0x66, 0xb1, 0x6d, 0xd9, 0x2b, 0x4e, 0xb4, 0xd2, 0x35, 0x13, 0x16, 0x2b, 0x02, 0xd0, 0xf7, 0x2a, 0x43, 0xa2, 0xfe, 0x4a, 0x5f, 0x97, 0xab};cipher_test_case_t aes_cbc_test_case_0 = { 30, /* octets in key */ aes_cbc_test_case_0_key, /* key */ 0, /* packet index */ 32, /* octets in plaintext */ aes_cbc_test_case_0_plaintext, /* plaintext */ aes_cbc_test_case_0_ciphertext, /* ciphertext */ NULL /* pointer to next testcase */};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -