michael@0: /* michael@0: * aes_calc.c michael@0: * michael@0: * A simple AES calculator for generating AES encryption values michael@0: * michael@0: * David A. McGrew michael@0: * Cisco Systems, Inc. michael@0: */ michael@0: /* michael@0: * michael@0: * Copyright (c) 2001-2006, Cisco Systems, Inc. michael@0: * All rights reserved. michael@0: * michael@0: * Redistribution and use in source and binary forms, with or without michael@0: * modification, are permitted provided that the following conditions michael@0: * are met: michael@0: * michael@0: * Redistributions of source code must retain the above copyright michael@0: * notice, this list of conditions and the following disclaimer. michael@0: * michael@0: * Redistributions in binary form must reproduce the above michael@0: * copyright notice, this list of conditions and the following michael@0: * disclaimer in the documentation and/or other materials provided michael@0: * with the distribution. michael@0: * michael@0: * Neither the name of the Cisco Systems, Inc. nor the names of its michael@0: * contributors may be used to endorse or promote products derived michael@0: * from this software without specific prior written permission. michael@0: * michael@0: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS michael@0: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT michael@0: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS michael@0: * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE michael@0: * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, michael@0: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES michael@0: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR michael@0: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) michael@0: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, michael@0: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) michael@0: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED michael@0: * OF THE POSSIBILITY OF SUCH DAMAGE. michael@0: * michael@0: */ michael@0: michael@0: /* michael@0: michael@0: Example usage (with first NIST FIPS 197 test case): michael@0: michael@0: [sh]$ test/aes_calc 000102030405060708090a0b0c0d0e0f 00112233445566778899aabbccddeeff -v michael@0: plaintext: 00112233445566778899aabbccddeeff michael@0: key: 000102030405060708090a0b0c0d0e0f michael@0: ciphertext: 69c4e0d86a7b0430d8cdb78070b4c55a michael@0: michael@0: */ michael@0: michael@0: #include "aes.h" michael@0: #include michael@0: #include michael@0: michael@0: void michael@0: usage(char *prog_name) { michael@0: printf("usage: %s [-v]\n", prog_name); michael@0: exit(255); michael@0: } michael@0: michael@0: #define AES_MAX_KEY_LEN 32 michael@0: michael@0: int michael@0: main (int argc, char *argv[]) { michael@0: v128_t data; michael@0: uint8_t key[AES_MAX_KEY_LEN]; michael@0: aes_expanded_key_t exp_key; michael@0: int key_len, len; michael@0: int verbose; michael@0: err_status_t status; michael@0: michael@0: if (argc == 3) { michael@0: /* we're not in verbose mode */ michael@0: verbose = 0; michael@0: } else if (argc == 4) { michael@0: if (strncmp(argv[3], "-v", 2) == 0) { michael@0: /* we're in verbose mode */ michael@0: verbose = 1; michael@0: } else { michael@0: /* unrecognized flag, complain and exit */ michael@0: usage(argv[0]); michael@0: } michael@0: } else { michael@0: /* we've been fed the wrong number of arguments - compain and exit */ michael@0: usage(argv[0]); michael@0: } michael@0: michael@0: /* read in key, checking length */ michael@0: if (strlen(argv[1]) > AES_MAX_KEY_LEN*2) { michael@0: fprintf(stderr, michael@0: "error: too many digits in key " michael@0: "(should be at most %d hexadecimal digits, found %u)\n", michael@0: AES_MAX_KEY_LEN*2, (unsigned)strlen(argv[1])); michael@0: exit(1); michael@0: } michael@0: len = hex_string_to_octet_string((char*)key, argv[1], AES_MAX_KEY_LEN*2); michael@0: /* check that hex string is the right length */ michael@0: if (len != 32 && len != 48 && len != 64) { michael@0: fprintf(stderr, michael@0: "error: bad number of digits in key " michael@0: "(should be 32/48/64 hexadecimal digits, found %d)\n", michael@0: len); michael@0: exit(1); michael@0: } michael@0: key_len = len/2; michael@0: michael@0: /* read in plaintext, checking length */ michael@0: if (strlen(argv[2]) > 16*2) { michael@0: fprintf(stderr, michael@0: "error: too many digits in plaintext " michael@0: "(should be %d hexadecimal digits, found %u)\n", michael@0: 16*2, (unsigned)strlen(argv[2])); michael@0: exit(1); michael@0: } michael@0: len = hex_string_to_octet_string((char *)(&data), argv[2], 16*2); michael@0: /* check that hex string is the right length */ michael@0: if (len < 16*2) { michael@0: fprintf(stderr, michael@0: "error: too few digits in plaintext " michael@0: "(should be %d hexadecimal digits, found %d)\n", michael@0: 16*2, len); michael@0: exit(1); michael@0: } michael@0: michael@0: if (verbose) { michael@0: /* print out plaintext */ michael@0: printf("plaintext:\t%s\n", octet_string_hex_string((uint8_t *)&data, 16)); michael@0: } michael@0: michael@0: /* encrypt plaintext */ michael@0: status = aes_expand_encryption_key(key, key_len, &exp_key); michael@0: if (status) { michael@0: fprintf(stderr, michael@0: "error: AES key expansion failed.\n"); michael@0: exit(1); michael@0: } michael@0: michael@0: aes_encrypt(&data, &exp_key); michael@0: michael@0: /* write ciphertext to output */ michael@0: if (verbose) { michael@0: printf("key:\t\t%s\n", octet_string_hex_string(key, key_len)); michael@0: printf("ciphertext:\t"); michael@0: } michael@0: printf("%s\n", v128_hex_string(&data)); michael@0: michael@0: return 0; michael@0: } michael@0: