ua_securitypolicy_mbedtls_common.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. #include <open62541/plugin/securitypolicy.h>
  2. #ifdef UA_ENABLE_ENCRYPTION
  3. #include <open62541/plugin/pki.h>
  4. #include <open62541/types.h>
  5. #include "ua_securitypolicy_mbedtls_common.h"
  6. #include <mbedtls/aes.h>
  7. #include <mbedtls/ctr_drbg.h>
  8. #include <mbedtls/entropy.h>
  9. #include <mbedtls/entropy_poll.h>
  10. #include <mbedtls/error.h>
  11. #include <mbedtls/md.h>
  12. #include <mbedtls/sha1.h>
  13. #include <mbedtls/version.h>
  14. #include <mbedtls/x509_crt.h>
  15. void
  16. swapBuffers(UA_ByteString *const bufA, UA_ByteString *const bufB) {
  17. UA_ByteString tmp = *bufA;
  18. *bufA = *bufB;
  19. *bufB = tmp;
  20. }
  21. void
  22. mbedtls_hmac(mbedtls_md_context_t *context, const UA_ByteString *key,
  23. const UA_ByteString *in, unsigned char *out) {
  24. mbedtls_md_hmac_starts(context, key->data, key->length);
  25. mbedtls_md_hmac_update(context, in->data, in->length);
  26. mbedtls_md_hmac_finish(context, out);
  27. }
  28. UA_StatusCode
  29. mbedtls_generateKey(mbedtls_md_context_t *context,
  30. const UA_ByteString *secret, const UA_ByteString *seed,
  31. UA_ByteString *out) {
  32. size_t hashLen = (size_t)mbedtls_md_get_size(context->md_info);
  33. UA_ByteString A_and_seed;
  34. UA_ByteString_allocBuffer(&A_and_seed, hashLen + seed->length);
  35. memcpy(A_and_seed.data + hashLen, seed->data, seed->length);
  36. UA_ByteString ANext_and_seed;
  37. UA_ByteString_allocBuffer(&ANext_and_seed, hashLen + seed->length);
  38. memcpy(ANext_and_seed.data + hashLen, seed->data, seed->length);
  39. UA_ByteString A = {
  40. hashLen,
  41. A_and_seed.data
  42. };
  43. UA_ByteString ANext = {
  44. hashLen,
  45. ANext_and_seed.data
  46. };
  47. mbedtls_hmac(context, secret, seed, A.data);
  48. UA_StatusCode retval = 0;
  49. for(size_t offset = 0; offset < out->length; offset += hashLen) {
  50. UA_ByteString outSegment = {
  51. hashLen,
  52. out->data + offset
  53. };
  54. UA_Boolean bufferAllocated = UA_FALSE;
  55. // Not enough room in out buffer to write the hash.
  56. if(offset + hashLen > out->length) {
  57. outSegment.data = NULL;
  58. outSegment.length = 0;
  59. retval = UA_ByteString_allocBuffer(&outSegment, hashLen);
  60. if(retval != UA_STATUSCODE_GOOD) {
  61. UA_ByteString_deleteMembers(&A_and_seed);
  62. UA_ByteString_deleteMembers(&ANext_and_seed);
  63. return retval;
  64. }
  65. bufferAllocated = UA_TRUE;
  66. }
  67. mbedtls_hmac(context, secret, &A_and_seed, outSegment.data);
  68. mbedtls_hmac(context, secret, &A, ANext.data);
  69. if(retval != UA_STATUSCODE_GOOD) {
  70. if(bufferAllocated)
  71. UA_ByteString_deleteMembers(&outSegment);
  72. UA_ByteString_deleteMembers(&A_and_seed);
  73. UA_ByteString_deleteMembers(&ANext_and_seed);
  74. return retval;
  75. }
  76. if(bufferAllocated) {
  77. memcpy(out->data + offset, outSegment.data, out->length - offset);
  78. UA_ByteString_deleteMembers(&outSegment);
  79. }
  80. swapBuffers(&ANext_and_seed, &A_and_seed);
  81. swapBuffers(&ANext, &A);
  82. }
  83. UA_ByteString_deleteMembers(&A_and_seed);
  84. UA_ByteString_deleteMembers(&ANext_and_seed);
  85. return UA_STATUSCODE_GOOD;
  86. }
  87. UA_StatusCode
  88. mbedtls_verifySig_sha1(mbedtls_x509_crt *certificate, const UA_ByteString *message,
  89. const UA_ByteString *signature) {
  90. /* Compute the sha1 hash */
  91. unsigned char hash[UA_SHA1_LENGTH];
  92. #if MBEDTLS_VERSION_NUMBER >= 0x02070000
  93. mbedtls_sha1_ret(message->data, message->length, hash);
  94. #else
  95. mbedtls_sha1(message->data, message->length, hash);
  96. #endif
  97. /* Set the RSA settings */
  98. mbedtls_rsa_context *rsaContext = mbedtls_pk_rsa(certificate->pk);
  99. if(!rsaContext)
  100. return UA_STATUSCODE_BADINTERNALERROR;
  101. mbedtls_rsa_set_padding(rsaContext, MBEDTLS_RSA_PKCS_V15, 0);
  102. /* Verify */
  103. int mbedErr = mbedtls_pk_verify(&certificate->pk,
  104. MBEDTLS_MD_SHA1, hash, UA_SHA1_LENGTH,
  105. signature->data, signature->length);
  106. if(mbedErr)
  107. return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
  108. return UA_STATUSCODE_GOOD;
  109. }
  110. UA_StatusCode
  111. mbedtls_sign_sha1(mbedtls_pk_context *localPrivateKey,
  112. mbedtls_ctr_drbg_context *drbgContext,
  113. const UA_ByteString *message,
  114. UA_ByteString *signature) {
  115. unsigned char hash[UA_SHA1_LENGTH];
  116. #if MBEDTLS_VERSION_NUMBER >= 0x02070000
  117. mbedtls_sha1_ret(message->data, message->length, hash);
  118. #else
  119. mbedtls_sha1(message->data, message->length, hash);
  120. #endif
  121. mbedtls_rsa_context *rsaContext = mbedtls_pk_rsa(*localPrivateKey);
  122. mbedtls_rsa_set_padding(rsaContext, MBEDTLS_RSA_PKCS_V15, 0);
  123. size_t sigLen = 0;
  124. int mbedErr = mbedtls_pk_sign(localPrivateKey, MBEDTLS_MD_SHA1, hash,
  125. UA_SHA1_LENGTH, signature->data, &sigLen,
  126. mbedtls_ctr_drbg_random, drbgContext);
  127. if(mbedErr)
  128. return UA_STATUSCODE_BADINTERNALERROR;
  129. return UA_STATUSCODE_GOOD;
  130. }
  131. UA_StatusCode
  132. mbedtls_thumbprint_sha1(const UA_ByteString *certificate,
  133. UA_ByteString *thumbprint) {
  134. if(UA_ByteString_equal(certificate, &UA_BYTESTRING_NULL))
  135. return UA_STATUSCODE_BADINTERNALERROR;
  136. if(thumbprint->length != UA_SHA1_LENGTH)
  137. return UA_STATUSCODE_BADINTERNALERROR;
  138. /* The certificate thumbprint is always a 20 bit sha1 hash, see Part 4 of the Specification. */
  139. #if MBEDTLS_VERSION_NUMBER >= 0x02070000
  140. mbedtls_sha1_ret(certificate->data, certificate->length, thumbprint->data);
  141. #else
  142. mbedtls_sha1(certificate->data, certificate->length, thumbprint->data);
  143. #endif
  144. return UA_STATUSCODE_GOOD;
  145. }
  146. UA_StatusCode
  147. mbedtls_encrypt_rsaOaep(mbedtls_rsa_context *context,
  148. mbedtls_ctr_drbg_context *drbgContext,
  149. UA_ByteString *data, const size_t plainTextBlockSize) {
  150. if(data->length % plainTextBlockSize != 0)
  151. return UA_STATUSCODE_BADINTERNALERROR;
  152. size_t max_blocks = data->length / plainTextBlockSize;
  153. UA_ByteString encrypted;
  154. UA_StatusCode retval = UA_ByteString_allocBuffer(&encrypted, max_blocks * context->len);
  155. if(retval != UA_STATUSCODE_GOOD)
  156. return retval;
  157. size_t lenDataToEncrypt = data->length;
  158. size_t inOffset = 0;
  159. size_t offset = 0;
  160. const unsigned char *label = NULL;
  161. while(lenDataToEncrypt >= plainTextBlockSize) {
  162. int mbedErr = mbedtls_rsa_rsaes_oaep_encrypt(context, mbedtls_ctr_drbg_random,
  163. drbgContext, MBEDTLS_RSA_PUBLIC,
  164. label, 0, plainTextBlockSize,
  165. data->data + inOffset, encrypted.data + offset);
  166. if(mbedErr) {
  167. UA_ByteString_deleteMembers(&encrypted);
  168. return UA_STATUSCODE_BADINTERNALERROR;
  169. }
  170. inOffset += plainTextBlockSize;
  171. offset += context->len;
  172. lenDataToEncrypt -= plainTextBlockSize;
  173. }
  174. memcpy(data->data, encrypted.data, offset);
  175. UA_ByteString_deleteMembers(&encrypted);
  176. return UA_STATUSCODE_GOOD;
  177. }
  178. UA_StatusCode
  179. mbedtls_decrypt_rsaOaep(mbedtls_pk_context *localPrivateKey,
  180. mbedtls_ctr_drbg_context *drbgContext,
  181. UA_ByteString *data) {
  182. mbedtls_rsa_context *rsaContext = mbedtls_pk_rsa(*localPrivateKey);
  183. mbedtls_rsa_set_padding(rsaContext, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA1);
  184. if(data->length % rsaContext->len != 0)
  185. return UA_STATUSCODE_BADINTERNALERROR;
  186. size_t inOffset = 0;
  187. size_t outOffset = 0;
  188. size_t outLength = 0;
  189. unsigned char buf[512];
  190. while(inOffset < data->length) {
  191. int mbedErr = mbedtls_rsa_rsaes_oaep_decrypt(rsaContext, mbedtls_ctr_drbg_random,
  192. drbgContext, MBEDTLS_RSA_PRIVATE,
  193. NULL, 0, &outLength,
  194. data->data + inOffset,
  195. buf, 512);
  196. if(mbedErr)
  197. return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
  198. memcpy(data->data + outOffset, buf, outLength);
  199. inOffset += rsaContext->len;
  200. outOffset += outLength;
  201. }
  202. data->length = outOffset;
  203. return UA_STATUSCODE_GOOD;
  204. }
  205. #endif