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 4.8KB

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