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.

cbc_test.c 5.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  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. * CBC 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 "cbc_test.h"
  38. /** Number of sample iterations for profiling */
  39. #define PROFILE_COUNT 16
  40. /**
  41. * Test CBC encryption
  42. *
  43. * @v cipher Cipher algorithm
  44. * @v key Key
  45. * @v key_len Length of key
  46. * @v iv Initialisation vector
  47. * @v plaintext Plaintext data
  48. * @v expected_ciphertext Expected ciphertext data
  49. * @v len Length of data
  50. * @ret ok Ciphertext is as expected
  51. */
  52. int cbc_test_encrypt ( struct cipher_algorithm *cipher, const void *key,
  53. size_t key_len, const void *iv, const void *plaintext,
  54. const void *expected_ciphertext, size_t len ) {
  55. uint8_t ctx[cipher->ctxsize];
  56. uint8_t ciphertext[len];
  57. int rc;
  58. /* Initialise cipher */
  59. rc = cipher_setkey ( cipher, ctx, key, key_len );
  60. assert ( rc == 0 );
  61. cipher_setiv ( cipher, ctx, iv );
  62. /* Perform encryption */
  63. cipher_encrypt ( cipher, ctx, plaintext, ciphertext, len );
  64. /* Verify result */
  65. return ( memcmp ( ciphertext, expected_ciphertext, len ) == 0 );
  66. }
  67. /**
  68. * Test CBC decryption
  69. *
  70. * @v cipher Cipher algorithm
  71. * @v key Key
  72. * @v key_len Length of key
  73. * @v iv Initialisation vector
  74. * @v ciphertext Ciphertext data
  75. * @v expected_plaintext Expected plaintext data
  76. * @v len Length of data
  77. * @ret ok Plaintext is as expected
  78. */
  79. int cbc_test_decrypt ( struct cipher_algorithm *cipher, const void *key,
  80. size_t key_len, const void *iv, const void *ciphertext,
  81. const void *expected_plaintext, size_t len ) {
  82. uint8_t ctx[cipher->ctxsize];
  83. uint8_t plaintext[len];
  84. int rc;
  85. /* Initialise cipher */
  86. rc = cipher_setkey ( cipher, ctx, key, key_len );
  87. assert ( rc == 0 );
  88. cipher_setiv ( cipher, ctx, iv );
  89. /* Perform encryption */
  90. cipher_decrypt ( cipher, ctx, ciphertext, plaintext, len );
  91. /* Verify result */
  92. return ( memcmp ( plaintext, expected_plaintext, len ) == 0 );
  93. }
  94. /**
  95. * Calculate CBC encryption or decryption cost
  96. *
  97. * @v cipher Cipher algorithm
  98. * @v key_len Length of key
  99. * @v op Encryption or decryption operation
  100. * @ret cost Cost (in cycles per byte)
  101. */
  102. static unsigned long cbc_cost ( struct cipher_algorithm *cipher,
  103. size_t key_len,
  104. void ( * op ) ( struct cipher_algorithm *cipher,
  105. void *ctx, const void *src,
  106. void *dst, size_t len ) ) {
  107. static uint8_t random[8192]; /* Too large for stack */
  108. uint8_t key[key_len];
  109. uint8_t iv[cipher->blocksize];
  110. uint8_t ctx[cipher->ctxsize];
  111. struct profiler profiler;
  112. unsigned long cost;
  113. unsigned int i;
  114. int rc;
  115. /* Fill buffer with pseudo-random data */
  116. srand ( 0x1234568 );
  117. for ( i = 0 ; i < sizeof ( random ) ; i++ )
  118. random[i] = rand();
  119. for ( i = 0 ; i < sizeof ( key ) ; i++ )
  120. key[i] = rand();
  121. for ( i = 0 ; i < sizeof ( iv ) ; i++ )
  122. iv[i] = rand();
  123. /* Initialise cipher */
  124. rc = cipher_setkey ( cipher, ctx, key, key_len );
  125. assert ( rc == 0 );
  126. cipher_setiv ( cipher, ctx, iv );
  127. /* Profile cipher operation */
  128. memset ( &profiler, 0, sizeof ( profiler ) );
  129. for ( i = 0 ; i < PROFILE_COUNT ; i++ ) {
  130. profile_start ( &profiler );
  131. op ( cipher, ctx, random, random, sizeof ( random ) );
  132. profile_stop ( &profiler );
  133. }
  134. /* Round to nearest whole number of cycles per byte */
  135. cost = ( ( profile_mean ( &profiler ) + ( sizeof ( random ) / 2 ) ) /
  136. sizeof ( random ) );
  137. return cost;
  138. }
  139. /**
  140. * Calculate CBC encryption cost
  141. *
  142. * @v cipher Cipher algorithm
  143. * @v key_len Length of key
  144. * @ret cost Cost (in cycles per byte)
  145. */
  146. unsigned long cbc_cost_encrypt ( struct cipher_algorithm *cipher,
  147. size_t key_len ) {
  148. return cbc_cost ( cipher, key_len, cipher_encrypt );
  149. }
  150. /**
  151. * Calculate CBC decryption cost
  152. *
  153. * @v cipher Cipher algorithm
  154. * @v key_len Length of key
  155. * @ret cost Cost (in cycles per byte)
  156. */
  157. unsigned long cbc_cost_decrypt ( struct cipher_algorithm *cipher,
  158. size_t key_len ) {
  159. return cbc_cost ( cipher, key_len, cipher_decrypt );
  160. }