tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

aes_calc.c (5477B)


      1 /*
      2 * aes_calc.c
      3 *
      4 * A simple AES calculator for generating AES encryption values
      5 *
      6 * David A. McGrew
      7 * Cisco Systems, Inc.
      8 */
      9 
     10 /*
     11 *
     12 * Copyright (c) 2001-2017, Cisco Systems, Inc.
     13 * All rights reserved.
     14 *
     15 * Redistribution and use in source and binary forms, with or without
     16 * modification, are permitted provided that the following conditions
     17 * are met:
     18 *
     19 *   Redistributions of source code must retain the above copyright
     20 *   notice, this list of conditions and the following disclaimer.
     21 *
     22 *   Redistributions in binary form must reproduce the above
     23 *   copyright notice, this list of conditions and the following
     24 *   disclaimer in the documentation and/or other materials provided
     25 *   with the distribution.
     26 *
     27 *   Neither the name of the Cisco Systems, Inc. nor the names of its
     28 *   contributors may be used to endorse or promote products derived
     29 *   from this software without specific prior written permission.
     30 *
     31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     34 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     35 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
     36 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     37 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     38 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     41 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
     42 * OF THE POSSIBILITY OF SUCH DAMAGE.
     43 *
     44 */
     45 
     46 /*
     47 
     48 Example usage (with first NIST FIPS 197 test case):
     49 
     50 [sh]$ test/aes_calc 000102030405060708090a0b0c0d0e0f \
     51       00112233445566778899aabbccddeeff -v
     52 
     53 plaintext:      00112233445566778899aabbccddeeff
     54 key:            000102030405060708090a0b0c0d0e0f
     55 ciphertext:     69c4e0d86a7b0430d8cdb78070b4c55a
     56 
     57 */
     58 
     59 #ifdef HAVE_CONFIG_H
     60 #include <config.h>
     61 #endif
     62 
     63 #include "aes.h"
     64 #include <stdio.h>
     65 #include <string.h>
     66 #include "util.h"
     67 
     68 void usage(char *prog_name)
     69 {
     70    printf("usage: %s <key> <plaintext> [<ciphertext>] [-v]\n", prog_name);
     71    exit(255);
     72 }
     73 
     74 #define AES_MAX_KEY_LEN 32
     75 
     76 int main(int argc, char *argv[])
     77 {
     78    const char *expected_ciphertext = NULL;
     79    const char *ciphertext = NULL;
     80    v128_t data;
     81    uint8_t key[AES_MAX_KEY_LEN];
     82    srtp_aes_expanded_key_t exp_key;
     83    int key_len, len;
     84    int verbose = 0;
     85    srtp_err_status_t status;
     86 
     87    /* -v must be last if it's passed */
     88    if (argc > 0 && strncmp(argv[argc - 1], "-v", 2) == 0) {
     89        /* we're in verbose mode */
     90        verbose = 1;
     91        --argc;
     92    }
     93 
     94    if (argc < 3 || argc > 4) {
     95        /* we've been fed the wrong number of arguments - compain and exit */
     96        usage(argv[0]);
     97    }
     98 
     99    if (argc == 4) {
    100        /* we're being passed the ciphertext to check (in unit test mode) */
    101        expected_ciphertext = argv[3];
    102        if (strlen(expected_ciphertext) != 16 * 2) {
    103            usage(argv[0]);
    104        }
    105    }
    106 
    107    /* read in key, checking length */
    108    if (strlen(argv[1]) > AES_MAX_KEY_LEN * 2) {
    109        fprintf(stderr,
    110                "error: too many digits in key "
    111                "(should be at most %d hexadecimal digits, found %u)\n",
    112                AES_MAX_KEY_LEN * 2, (unsigned)strlen(argv[1]));
    113        exit(1);
    114    }
    115    len = hex_string_to_octet_string((char *)key, argv[1], AES_MAX_KEY_LEN * 2);
    116    /* check that hex string is the right length */
    117    if (len != 32 && len != 48 && len != 64) {
    118        fprintf(stderr,
    119                "error: bad number of digits in key "
    120                "(should be 32/48/64 hexadecimal digits, found %d)\n",
    121                len);
    122        exit(1);
    123    }
    124    key_len = len / 2;
    125 
    126    /* read in plaintext, checking length */
    127    if (strlen(argv[2]) > 16 * 2) {
    128        fprintf(stderr,
    129                "error: too many digits in plaintext "
    130                "(should be %d hexadecimal digits, found %u)\n",
    131                16 * 2, (unsigned)strlen(argv[2]));
    132        exit(1);
    133    }
    134    len = hex_string_to_octet_string((char *)(&data), argv[2], 16 * 2);
    135    /* check that hex string is the right length */
    136    if (len < 16 * 2) {
    137        fprintf(stderr,
    138                "error: too few digits in plaintext "
    139                "(should be %d hexadecimal digits, found %d)\n",
    140                16 * 2, len);
    141        exit(1);
    142    }
    143 
    144    if (verbose) {
    145        /* print out plaintext */
    146        printf("plaintext:\t%s\n",
    147               octet_string_hex_string((uint8_t *)&data, 16));
    148    }
    149 
    150    /* encrypt plaintext */
    151    status = srtp_aes_expand_encryption_key(key, key_len, &exp_key);
    152    if (status) {
    153        fprintf(stderr, "error: AES key expansion failed.\n");
    154        exit(1);
    155    }
    156 
    157    srtp_aes_encrypt(&data, &exp_key);
    158 
    159    /* write ciphertext to output */
    160    if (verbose) {
    161        printf("key:\t\t%s\n", octet_string_hex_string(key, key_len));
    162        printf("ciphertext:\t");
    163    }
    164 
    165    ciphertext = v128_hex_string(&data);
    166    printf("%s\n", ciphertext);
    167 
    168    if (expected_ciphertext && strcmp(ciphertext, expected_ciphertext) != 0) {
    169        fprintf(stderr,
    170                "error: calculated ciphertext %s does not match "
    171                "expected ciphertext %s\n",
    172                ciphertext, expected_ciphertext);
    173        exit(1);
    174    }
    175 
    176    return 0;
    177 }