16ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org/* 26ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org * aes_calc.c 36ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org * 46ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org * A simple AES calculator for generating AES encryption values 56ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org * 66ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org * David A. McGrew 76ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org * Cisco Systems, Inc. 86ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org */ 95961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com/* 105961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * 115961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * Copyright (c) 2001-2006, Cisco Systems, Inc. 125961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * All rights reserved. 135961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * 145961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * Redistribution and use in source and binary forms, with or without 155961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * modification, are permitted provided that the following conditions 165961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * are met: 175961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * 185961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * Redistributions of source code must retain the above copyright 195961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * notice, this list of conditions and the following disclaimer. 205961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * 215961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * Redistributions in binary form must reproduce the above 225961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * copyright notice, this list of conditions and the following 235961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * disclaimer in the documentation and/or other materials provided 245961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * with the distribution. 255961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * 265961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * Neither the name of the Cisco Systems, Inc. nor the names of its 275961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * contributors may be used to endorse or promote products derived 285961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * from this software without specific prior written permission. 295961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * 305961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 315961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 325961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 335961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 345961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 355961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 365961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 375961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 385961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 395961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 405961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 415961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * OF THE POSSIBILITY OF SUCH DAMAGE. 425961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * 435961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com */ 446ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org 456ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org/* 466ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org 476ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org Example usage (with first NIST FIPS 197 test case): 486ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org 496ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org[sh]$ test/aes_calc 000102030405060708090a0b0c0d0e0f 00112233445566778899aabbccddeeff -v 506ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org plaintext: 00112233445566778899aabbccddeeff 516ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org key: 000102030405060708090a0b0c0d0e0f 526ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org ciphertext: 69c4e0d86a7b0430d8cdb78070b4c55a 536ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org 546ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org */ 556ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org 566ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org#include "aes.h" 576ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org#include <stdio.h> 586ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org#include <string.h> 596ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org 606ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.orgvoid 616ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.orgusage(char *prog_name) { 626ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org printf("usage: %s <key> <plaintext> [-v]\n", prog_name); 636ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org exit(255); 646ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org} 656ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org 666ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org#define AES_MAX_KEY_LEN 32 676ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org 686ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.orgint 696ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.orgmain (int argc, char *argv[]) { 706ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org v128_t data; 716ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org uint8_t key[AES_MAX_KEY_LEN]; 726ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org aes_expanded_key_t exp_key; 736ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org int key_len, len; 746ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org int verbose; 756ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org err_status_t status; 766ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org 776ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org if (argc == 3) { 786ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org /* we're not in verbose mode */ 796ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org verbose = 0; 806ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org } else if (argc == 4) { 816ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org if (strncmp(argv[3], "-v", 2) == 0) { 826ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org /* we're in verbose mode */ 836ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org verbose = 1; 846ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org } else { 856ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org /* unrecognized flag, complain and exit */ 866ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org usage(argv[0]); 876ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org } 886ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org } else { 896ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org /* we've been fed the wrong number of arguments - compain and exit */ 906ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org usage(argv[0]); 916ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org } 926ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org 936ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org /* read in key, checking length */ 946ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org if (strlen(argv[1]) > AES_MAX_KEY_LEN*2) { 956ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org fprintf(stderr, 966ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org "error: too many digits in key " 976ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org "(should be at most %d hexadecimal digits, found %u)\n", 986ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org AES_MAX_KEY_LEN*2, (unsigned)strlen(argv[1])); 996ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org exit(1); 1006ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org } 1016ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org len = hex_string_to_octet_string((char*)key, argv[1], AES_MAX_KEY_LEN*2); 1026ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org /* check that hex string is the right length */ 1036ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org if (len != 32 && len != 48 && len != 64) { 1046ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org fprintf(stderr, 1056ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org "error: bad number of digits in key " 1066ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org "(should be 32/48/64 hexadecimal digits, found %d)\n", 1076ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org len); 1086ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org exit(1); 1096ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org } 1106ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org key_len = len/2; 1116ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org 1126ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org /* read in plaintext, checking length */ 1136ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org if (strlen(argv[2]) > 16*2) { 1146ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org fprintf(stderr, 1156ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org "error: too many digits in plaintext " 1166ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org "(should be %d hexadecimal digits, found %u)\n", 1176ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org 16*2, (unsigned)strlen(argv[2])); 1186ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org exit(1); 1196ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org } 1206ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org len = hex_string_to_octet_string((char *)(&data), argv[2], 16*2); 1216ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org /* check that hex string is the right length */ 1226ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org if (len < 16*2) { 1236ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org fprintf(stderr, 1246ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org "error: too few digits in plaintext " 1256ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org "(should be %d hexadecimal digits, found %d)\n", 1266ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org 16*2, len); 1276ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org exit(1); 1286ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org } 1296ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org 1306ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org if (verbose) { 1316ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org /* print out plaintext */ 1326ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org printf("plaintext:\t%s\n", octet_string_hex_string((uint8_t *)&data, 16)); 1336ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org } 1346ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org 1356ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org /* encrypt plaintext */ 1366ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org status = aes_expand_encryption_key(key, key_len, &exp_key); 1376ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org if (status) { 1386ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org fprintf(stderr, 1396ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org "error: AES key expansion failed.\n"); 1406ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org exit(1); 1416ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org } 1426ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org 1436ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org aes_encrypt(&data, &exp_key); 1446ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org 1456ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org /* write ciphertext to output */ 1466ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org if (verbose) { 1476ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org printf("key:\t\t%s\n", octet_string_hex_string(key, key_len)); 1486ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org printf("ciphertext:\t"); 1496ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org } 1506ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org printf("%s\n", v128_hex_string(&data)); 1516ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org 1526ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org return 0; 1536ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org} 1546ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org 155