cryptography ip-cores in vhdl / verilog
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.

182 lines
3.7 KiB

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <openssl/conf.h>
  4. #include <openssl/evp.h>
  5. #include <openssl/err.h>
  6. static const char HDL_LOGIC_CHAR[] = { 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-'};
  7. enum HDL_LOGIC_STATES {
  8. HDL_U = 0,
  9. HDL_X = 1,
  10. HDL_0 = 2,
  11. HDL_1 = 3,
  12. HDL_Z = 4,
  13. HDL_W = 5,
  14. HDL_L = 6,
  15. HDL_H = 7,
  16. HDL_D = 8,
  17. };
  18. void slv_to_uchar(char* datain, unsigned char* dataout, int bytelen) {
  19. for (int i = 0; i < bytelen; i++) {
  20. for (int y = 0; y < 8; y++) {
  21. if (*datain == HDL_1) {
  22. *dataout |= 1 << y;
  23. } else if (*datain == HDL_0) {
  24. *dataout &= ~(1 << y);
  25. }
  26. datain++;
  27. }
  28. dataout++;
  29. }
  30. return;
  31. }
  32. void slv_to_string(char* datain, char* dataout, int bytelen) {
  33. for (int i = 0; i < bytelen; i++) {
  34. *dataout = HDL_LOGIC_CHAR[*datain];
  35. datain++;
  36. dataout++;
  37. }
  38. return;
  39. }
  40. void uchar_to_slv(unsigned char* datain, char* dataout, int bytelen) {
  41. for (int i = 0; i < bytelen; i++) {
  42. for (int y = 0; y < 8; y++) {
  43. if ((*datain >> y) & 1 == 1) {
  44. *dataout = HDL_1 ;
  45. } else {
  46. *dataout = HDL_0;
  47. }
  48. dataout++;
  49. }
  50. datain++;
  51. }
  52. return;
  53. }
  54. void handleErrors(void) {
  55. ERR_print_errors_fp(stderr);
  56. abort();
  57. }
  58. int encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key,
  59. unsigned char *ciphertext) {
  60. EVP_CIPHER_CTX *ctx;
  61. int len;
  62. int ciphertext_len;
  63. // Create and initialise the context
  64. if(!(ctx = EVP_CIPHER_CTX_new()))
  65. handleErrors();
  66. // Initialise the encryption operation, no IV needed in ECB mode
  67. if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, key, NULL))
  68. handleErrors();
  69. // We don't want padding
  70. if(1 != EVP_CIPHER_CTX_set_padding(ctx, 0))
  71. handleErrors();
  72. // Provide the message to be encrypted, and obtain the encrypted output
  73. if(1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len))
  74. handleErrors();
  75. ciphertext_len = len;
  76. // Finalise the encryption. No further bytes are written as padding is switched off
  77. if(1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len))
  78. handleErrors();
  79. ciphertext_len += len;
  80. // Clean up
  81. EVP_CIPHER_CTX_free(ctx);
  82. return ciphertext_len;
  83. }
  84. int decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key,
  85. unsigned char *plaintext) {
  86. EVP_CIPHER_CTX *ctx;
  87. int len;
  88. int plaintext_len;
  89. // Create and initialise the context
  90. if(!(ctx = EVP_CIPHER_CTX_new()))
  91. handleErrors();
  92. // Initialise the decryption operation, no IV needed in ECB mode
  93. if(1 != EVP_DecryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, key, NULL))
  94. handleErrors();
  95. // We don't want padding
  96. if(1 != EVP_CIPHER_CTX_set_padding(ctx, 0))
  97. handleErrors();
  98. // Provide the message to be decrypted, and obtain the decrypted output
  99. if(1 != EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len))
  100. handleErrors();
  101. plaintext_len = len;
  102. // Finalise the decryption. No further bytes are written as padding is switched off
  103. if(1 != EVP_DecryptFinal_ex(ctx, plaintext + len, &len))
  104. handleErrors();
  105. plaintext_len += len;
  106. // Clean up
  107. EVP_CIPHER_CTX_free(ctx);
  108. return plaintext_len;
  109. }
  110. void cryptData(char* datain, char* key, char mode, char* dataout, int bytelen) {
  111. int crypt_len;
  112. unsigned char c_din[bytelen];
  113. unsigned char c_key[bytelen];
  114. unsigned char c_dout[bytelen];
  115. slv_to_uchar(datain, c_din, bytelen);
  116. slv_to_uchar(key, c_key, bytelen);
  117. if (mode) {
  118. crypt_len = encrypt(c_din, bytelen, c_key, c_dout);
  119. } else {
  120. crypt_len = decrypt(c_din, bytelen, c_key, c_dout);
  121. }
  122. if (crypt_len != 16) {
  123. printf("Warning: crypt operation returned with unexpected length %d\n", crypt_len);
  124. }
  125. uchar_to_slv(c_dout, dataout, bytelen);
  126. return;
  127. }