crypt_burn.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. /*
  2. * Copyright (C) 2010 Martin Willi
  3. * Copyright (C) 2010 revosec AG
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of the GNU General Public License as published by the
  7. * Free Software Foundation; either version 2 of the License, or (at your
  8. * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
  9. *
  10. * This program is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  12. * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  13. * for more details.
  14. */
  15. #include <stdio.h>
  16. #include <library.h>
  17. static int burn_crypter(const proposal_token_t *token, u_int limit, u_int len)
  18. {
  19. chunk_t iv, key, data;
  20. crypter_t *crypter;
  21. int i = 0;
  22. bool ok;
  23. crypter = lib->crypto->create_crypter(lib->crypto, token->algorithm,
  24. token->keysize / 8);
  25. if (!crypter)
  26. {
  27. fprintf(stderr, "%N-%zu not supported\n",
  28. encryption_algorithm_names, token->algorithm, token->keysize);
  29. return FALSE;
  30. }
  31. iv = chunk_alloc(crypter->get_iv_size(crypter));
  32. memset(iv.ptr, 0xFF, iv.len);
  33. data = chunk_alloc(round_up(len, crypter->get_block_size(crypter)));
  34. memset(data.ptr, 0xDD, data.len);
  35. key = chunk_alloc(crypter->get_key_size(crypter));
  36. memset(key.ptr, 0xAA, key.len);
  37. ok = crypter->set_key(crypter, key);
  38. while (ok)
  39. {
  40. if (!crypter->encrypt(crypter, data, iv, NULL))
  41. {
  42. fprintf(stderr, "encryption failed!\n");
  43. ok = FALSE;
  44. break;
  45. }
  46. if (!crypter->decrypt(crypter, data, iv, NULL))
  47. {
  48. fprintf(stderr, "decryption failed!\n");
  49. ok = FALSE;
  50. break;
  51. }
  52. if (limit && ++i == limit)
  53. {
  54. break;
  55. }
  56. }
  57. crypter->destroy(crypter);
  58. free(iv.ptr);
  59. free(data.ptr);
  60. free(key.ptr);
  61. return ok;
  62. }
  63. static bool burn_aead(const proposal_token_t *token, u_int limit, u_int len)
  64. {
  65. chunk_t iv, key, data, dataicv, assoc;
  66. aead_t *aead;
  67. int i = 0;
  68. bool ok;
  69. aead = lib->crypto->create_aead(lib->crypto, token->algorithm,
  70. token->keysize / 8, 0);
  71. if (!aead)
  72. {
  73. fprintf(stderr, "%N-%zu not supported\n",
  74. encryption_algorithm_names, token->algorithm, token->keysize);
  75. return FALSE;
  76. }
  77. iv = chunk_alloc(aead->get_iv_size(aead));
  78. memset(iv.ptr, 0xFF, iv.len);
  79. dataicv = chunk_alloc(round_up(len, aead->get_block_size(aead)) +
  80. aead->get_icv_size(aead));
  81. data = chunk_create(dataicv.ptr, dataicv.len - aead->get_icv_size(aead));
  82. memset(data.ptr, 0xDD, data.len);
  83. assoc = chunk_alloc(13);
  84. memset(assoc.ptr, 0xCC, assoc.len);
  85. key = chunk_alloc(aead->get_key_size(aead));
  86. memset(key.ptr, 0xAA, key.len);
  87. ok = aead->set_key(aead, key);
  88. while (ok)
  89. {
  90. if (!aead->encrypt(aead, data, assoc, iv, NULL))
  91. {
  92. fprintf(stderr, "aead encryption failed!\n");
  93. ok = FALSE;
  94. break;
  95. }
  96. if (!aead->decrypt(aead, dataicv, assoc, iv, NULL))
  97. {
  98. fprintf(stderr, "aead integrity check failed!\n");
  99. ok = FALSE;
  100. break;
  101. }
  102. if (limit && ++i == limit)
  103. {
  104. break;
  105. }
  106. }
  107. aead->destroy(aead);
  108. free(iv.ptr);
  109. free(data.ptr);
  110. free(key.ptr);
  111. free(assoc.ptr);
  112. return ok;
  113. }
  114. static int burn_signer(const proposal_token_t *token, u_int limit, u_int len)
  115. {
  116. chunk_t key, data, sig;
  117. signer_t *signer;
  118. int i = 0;
  119. bool ok;
  120. signer = lib->crypto->create_signer(lib->crypto, token->algorithm);
  121. if (!signer)
  122. {
  123. fprintf(stderr, "%N not supported\n",
  124. integrity_algorithm_names, token->algorithm);
  125. return FALSE;
  126. }
  127. data = chunk_alloc(len);
  128. memset(data.ptr, 0xDD, data.len);
  129. key = chunk_alloc(signer->get_key_size(signer));
  130. memset(key.ptr, 0xAA, key.len);
  131. sig = chunk_alloc(signer->get_block_size(signer));
  132. ok = signer->set_key(signer, key);
  133. while (ok)
  134. {
  135. if (!signer->get_signature(signer, data, sig.ptr))
  136. {
  137. fprintf(stderr, "creating signature failed!\n");
  138. ok = FALSE;
  139. break;
  140. }
  141. if (!signer->verify_signature(signer, data, sig))
  142. {
  143. fprintf(stderr, "verifying signature failed!\n");
  144. ok = FALSE;
  145. break;
  146. }
  147. if (limit && ++i == limit)
  148. {
  149. break;
  150. }
  151. }
  152. signer->destroy(signer);
  153. free(data.ptr);
  154. free(key.ptr);
  155. free(sig.ptr);
  156. return ok;
  157. }
  158. int main(int argc, char *argv[])
  159. {
  160. const proposal_token_t *token;
  161. u_int limit = 0, len = 1024;
  162. bool ok;
  163. library_init(NULL, "crypt_burn");
  164. lib->plugins->load(lib->plugins, getenv("PLUGINS") ?: PLUGINS);
  165. atexit(library_deinit);
  166. fprintf(stderr, "loaded: %s\n", lib->plugins->loaded_plugins(lib->plugins));
  167. if (argc < 2)
  168. {
  169. fprintf(stderr, "usage: %s <algorithm> [buflen=%u] [rounds=%u]\n",
  170. argv[0], len, limit);
  171. return 1;
  172. }
  173. if (argc > 2)
  174. {
  175. len = atoi(argv[2]);
  176. }
  177. if (argc > 3)
  178. {
  179. limit = atoi(argv[3]);
  180. }
  181. token = lib->proposal->get_token(lib->proposal, argv[1]);
  182. if (!token)
  183. {
  184. fprintf(stderr, "algorithm '%s' unknown!\n", argv[1]);
  185. return 1;
  186. }
  187. switch (token->type)
  188. {
  189. case ENCRYPTION_ALGORITHM:
  190. if (encryption_algorithm_is_aead(token->algorithm))
  191. {
  192. ok = burn_aead(token, limit, len);
  193. }
  194. else
  195. {
  196. ok = burn_crypter(token, limit, len);
  197. }
  198. break;
  199. case INTEGRITY_ALGORITHM:
  200. ok = burn_signer(token, limit, len);
  201. break;
  202. default:
  203. fprintf(stderr, "'%s' is not a crypter/aead algorithm!\n", argv[1]);
  204. ok = FALSE;
  205. break;
  206. }
  207. return !ok;
  208. }