ua_securitypolicy_mbedtls_common.c 8.2 KB

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