aes_calc.c 5.3 KB

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