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.6KB

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