aes-encrypt.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (c) 2019,Softathome
  4. */
  5. #include "mkimage.h"
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <image.h>
  9. #include <time.h>
  10. #include <openssl/bn.h>
  11. #include <openssl/rsa.h>
  12. #include <openssl/pem.h>
  13. #include <openssl/err.h>
  14. #include <openssl/ssl.h>
  15. #include <openssl/evp.h>
  16. #include <openssl/engine.h>
  17. #include <uboot_aes.h>
  18. #if OPENSSL_VERSION_NUMBER >= 0x10000000L
  19. #define HAVE_ERR_REMOVE_THREAD_STATE
  20. #endif
  21. int image_aes_encrypt(struct image_cipher_info *info,
  22. unsigned char *data, int size,
  23. unsigned char **cipher, int *cipher_len)
  24. {
  25. EVP_CIPHER_CTX *ctx;
  26. unsigned char *buf = NULL;
  27. int buf_len, len, ret = 0;
  28. /* create and initialise the context */
  29. ctx = EVP_CIPHER_CTX_new();
  30. if (!ctx) {
  31. printf("Can't create context\n");
  32. return -1;
  33. }
  34. /* allocate a buffer for the result */
  35. buf = malloc(size + AES_BLOCK_LENGTH);
  36. if (!buf) {
  37. printf("Can't allocate memory to encrypt\n");
  38. ret = -1;
  39. goto out;
  40. }
  41. if (EVP_EncryptInit_ex(ctx, info->cipher->calculate_type(),
  42. NULL, info->key, info->iv) != 1) {
  43. printf("Can't init encryption\n");
  44. ret = -1;
  45. goto out;
  46. }
  47. if (EVP_EncryptUpdate(ctx, buf, &len, data, size) != 1) {
  48. printf("Can't encrypt data\n");
  49. ret = -1;
  50. goto out;
  51. }
  52. buf_len = len;
  53. if (EVP_EncryptFinal_ex(ctx, buf + len, &len) != 1) {
  54. printf("Can't finalise the encryption\n");
  55. ret = -1;
  56. goto out;
  57. }
  58. buf_len += len;
  59. *cipher = buf;
  60. *cipher_len = buf_len;
  61. out:
  62. EVP_CIPHER_CTX_free(ctx);
  63. return ret;
  64. }
  65. int image_aes_add_cipher_data(struct image_cipher_info *info, void *keydest,
  66. void *fit, int node_noffset)
  67. {
  68. int parent, node;
  69. char name[128];
  70. int ret = 0;
  71. /* Either create or overwrite the named cipher node */
  72. parent = fdt_subnode_offset(keydest, 0, FIT_CIPHER_NODENAME);
  73. if (parent == -FDT_ERR_NOTFOUND) {
  74. parent = fdt_add_subnode(keydest, 0, FIT_CIPHER_NODENAME);
  75. if (parent < 0) {
  76. ret = parent;
  77. if (ret != -FDT_ERR_NOSPACE) {
  78. fprintf(stderr,
  79. "Couldn't create cipher node: %s\n",
  80. fdt_strerror(parent));
  81. }
  82. }
  83. }
  84. if (ret)
  85. goto done;
  86. /* Either create or overwrite the named key node */
  87. if (info->ivname)
  88. snprintf(name, sizeof(name), "key-%s-%s-%s",
  89. info->name, info->keyname, info->ivname);
  90. else
  91. snprintf(name, sizeof(name), "key-%s-%s",
  92. info->name, info->keyname);
  93. node = fdt_subnode_offset(keydest, parent, name);
  94. if (node == -FDT_ERR_NOTFOUND) {
  95. node = fdt_add_subnode(keydest, parent, name);
  96. if (node < 0) {
  97. ret = node;
  98. if (ret != -FDT_ERR_NOSPACE) {
  99. fprintf(stderr,
  100. "Could not create key subnode: %s\n",
  101. fdt_strerror(node));
  102. }
  103. }
  104. } else if (node < 0) {
  105. fprintf(stderr, "Cannot select keys parent: %s\n",
  106. fdt_strerror(node));
  107. ret = node;
  108. }
  109. if (ret)
  110. goto done;
  111. if (info->ivname)
  112. /* Store the IV in the u-boot device tree */
  113. ret = fdt_setprop(keydest, node, "iv",
  114. info->iv, info->cipher->iv_len);
  115. else
  116. /* Store the IV in the FIT image */
  117. ret = fdt_setprop(fit, node_noffset, "iv",
  118. info->iv, info->cipher->iv_len);
  119. if (!ret)
  120. ret = fdt_setprop(keydest, node, "key",
  121. info->key, info->cipher->key_len);
  122. if (!ret)
  123. ret = fdt_setprop_u32(keydest, node, "key-len",
  124. info->cipher->key_len);
  125. done:
  126. if (ret)
  127. ret = ret == -FDT_ERR_NOSPACE ? -ENOSPC : -EIO;
  128. return ret;
  129. }