You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

cipher_test.c 5.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /*
  2. * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation; either version 2 of the
  7. * License, or any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful, but
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  17. * 02110-1301, USA.
  18. *
  19. * You can also choose to distribute this program under the terms of
  20. * the Unmodified Binary Distribution Licence (as given in the file
  21. * COPYING.UBDL), provided that you have satisfied its requirements.
  22. */
  23. FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  24. /** @file
  25. *
  26. * Cipher self-tests
  27. *
  28. */
  29. /* Forcibly enable assertions */
  30. #undef NDEBUG
  31. #include <stdint.h>
  32. #include <stdlib.h>
  33. #include <string.h>
  34. #include <assert.h>
  35. #include <ipxe/crypto.h>
  36. #include <ipxe/profile.h>
  37. #include <ipxe/test.h>
  38. #include "cipher_test.h"
  39. /** Number of sample iterations for profiling */
  40. #define PROFILE_COUNT 16
  41. /**
  42. * Report a cipher encryption test result
  43. *
  44. * @v test Cipher test
  45. * @v file Test code file
  46. * @v line Test code line
  47. */
  48. void cipher_encrypt_okx ( struct cipher_test *test, const char *file,
  49. unsigned int line ) {
  50. struct cipher_algorithm *cipher = test->cipher;
  51. size_t len = test->len;
  52. uint8_t ctx[cipher->ctxsize];
  53. uint8_t ciphertext[len];
  54. /* Initialise cipher */
  55. okx ( cipher_setkey ( cipher, ctx, test->key, test->key_len ) == 0,
  56. file, line );
  57. cipher_setiv ( cipher, ctx, test->iv );
  58. /* Perform encryption */
  59. cipher_encrypt ( cipher, ctx, test->plaintext, ciphertext, len );
  60. /* Compare against expected ciphertext */
  61. okx ( memcmp ( ciphertext, test->ciphertext, len ) == 0, file, line );
  62. }
  63. /**
  64. * Report a cipher decryption test result
  65. *
  66. * @v test Cipher test
  67. * @v file Test code file
  68. * @v line Test code line
  69. */
  70. void cipher_decrypt_okx ( struct cipher_test *test, const char *file,
  71. unsigned int line ) {
  72. struct cipher_algorithm *cipher = test->cipher;
  73. size_t len = test->len;
  74. uint8_t ctx[cipher->ctxsize];
  75. uint8_t plaintext[len];
  76. /* Initialise cipher */
  77. okx ( cipher_setkey ( cipher, ctx, test->key, test->key_len ) == 0,
  78. file, line );
  79. cipher_setiv ( cipher, ctx, test->iv );
  80. /* Perform encryption */
  81. cipher_decrypt ( cipher, ctx, test->ciphertext, plaintext, len );
  82. /* Compare against expected plaintext */
  83. okx ( memcmp ( plaintext, test->plaintext, len ) == 0, file, line );
  84. }
  85. /**
  86. * Report a cipher encryption and decryption test result
  87. *
  88. * @v test Cipher test
  89. * @v file Test code file
  90. * @v line Test code line
  91. */
  92. void cipher_okx ( struct cipher_test *test, const char *file,
  93. unsigned int line ) {
  94. cipher_encrypt_okx ( test, file, line );
  95. cipher_decrypt_okx ( test, file, line );
  96. }
  97. /**
  98. * Calculate cipher encryption or decryption cost
  99. *
  100. * @v cipher Cipher algorithm
  101. * @v key_len Length of key
  102. * @v op Encryption or decryption operation
  103. * @ret cost Cost (in cycles per byte)
  104. */
  105. static unsigned long
  106. cipher_cost ( struct cipher_algorithm *cipher, size_t key_len,
  107. void ( * op ) ( struct cipher_algorithm *cipher, void *ctx,
  108. const void *src, void *dst, size_t len ) ) {
  109. static uint8_t random[8192]; /* Too large for stack */
  110. uint8_t key[key_len];
  111. uint8_t iv[cipher->blocksize];
  112. uint8_t ctx[cipher->ctxsize];
  113. struct profiler profiler;
  114. unsigned long cost;
  115. unsigned int i;
  116. int rc;
  117. /* Fill buffer with pseudo-random data */
  118. srand ( 0x1234568 );
  119. for ( i = 0 ; i < sizeof ( random ) ; i++ )
  120. random[i] = rand();
  121. for ( i = 0 ; i < sizeof ( key ) ; i++ )
  122. key[i] = rand();
  123. for ( i = 0 ; i < sizeof ( iv ) ; i++ )
  124. iv[i] = rand();
  125. /* Initialise cipher */
  126. rc = cipher_setkey ( cipher, ctx, key, key_len );
  127. assert ( rc == 0 );
  128. cipher_setiv ( cipher, ctx, iv );
  129. /* Profile cipher operation */
  130. memset ( &profiler, 0, sizeof ( profiler ) );
  131. for ( i = 0 ; i < PROFILE_COUNT ; i++ ) {
  132. profile_start ( &profiler );
  133. op ( cipher, ctx, random, random, sizeof ( random ) );
  134. profile_stop ( &profiler );
  135. }
  136. /* Round to nearest whole number of cycles per byte */
  137. cost = ( ( profile_mean ( &profiler ) + ( sizeof ( random ) / 2 ) ) /
  138. sizeof ( random ) );
  139. return cost;
  140. }
  141. /**
  142. * Calculate cipher encryption cost
  143. *
  144. * @v cipher Cipher algorithm
  145. * @v key_len Length of key
  146. * @ret cost Cost (in cycles per byte)
  147. */
  148. unsigned long cipher_cost_encrypt ( struct cipher_algorithm *cipher,
  149. size_t key_len ) {
  150. return cipher_cost ( cipher, key_len, cipher_encrypt );
  151. }
  152. /**
  153. * Calculate cipher decryption cost
  154. *
  155. * @v cipher Cipher algorithm
  156. * @v key_len Length of key
  157. * @ret cost Cost (in cycles per byte)
  158. */
  159. unsigned long cipher_cost_decrypt ( struct cipher_algorithm *cipher,
  160. size_t key_len ) {
  161. return cipher_cost ( cipher, key_len, cipher_decrypt );
  162. }