crypto.c 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. #include <openssl/evp.h>
  2. #include <openssl/dh.h>
  3. #include <openssl/bn.h>
  4. #include <openssl/err.h>
  5. #include <openssl/rand.h>
  6. #include <openssl/ssl.h>
  7. #include "crypto.h"
  8. /* PRF using sha384, as defined in RFC 5246 */
  9. int PRF(uint8_t *secret, int32_t secret_len,
  10. uint8_t *seed1, int32_t seed1_len,
  11. uint8_t *seed2, int32_t seed2_len,
  12. uint8_t *seed3, int32_t seed3_len,
  13. uint8_t *seed4, int32_t seed4_len,
  14. uint8_t *output, int32_t output_len){
  15. EVP_MD_CTX ctx, ctx_tmp, ctx_init;
  16. EVP_PKEY *mac_key;
  17. const EVP_MD *md = EVP_sha384();
  18. uint8_t A[EVP_MAX_MD_SIZE];
  19. size_t len, A_len;
  20. int chunk = EVP_MD_size(md);
  21. int remaining = output_len;
  22. uint8_t *out = output;
  23. EVP_MD_CTX_init(&ctx);
  24. EVP_MD_CTX_init(&ctx_tmp);
  25. EVP_MD_CTX_init(&ctx_init);
  26. EVP_MD_CTX_set_flags(&ctx_init, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
  27. mac_key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, secret, secret_len);
  28. /* Calculate first A value */
  29. EVP_DigestSignInit(&ctx_init, NULL, md, NULL, mac_key);
  30. EVP_MD_CTX_copy_ex(&ctx, &ctx_init);
  31. if(seed1 != NULL && seed1_len > 0){
  32. EVP_DigestSignUpdate(&ctx, seed1, seed1_len);
  33. }
  34. if(seed2 != NULL && seed2_len > 0){
  35. EVP_DigestSignUpdate(&ctx, seed2, seed2_len);
  36. }
  37. if(seed3 != NULL && seed3_len > 0){
  38. EVP_DigestSignUpdate(&ctx, seed3, seed3_len);
  39. }
  40. if(seed4 != NULL && seed4_len > 0){
  41. EVP_DigestSignUpdate(&ctx, seed4, seed4_len);
  42. }
  43. EVP_DigestSignFinal(&ctx, A, &A_len);
  44. //iterate until desired length is achieved
  45. while(remaining > 0){
  46. /* Now compute SHA384(secret, A+seed) */
  47. EVP_MD_CTX_copy_ex(&ctx, &ctx_init);
  48. EVP_DigestSignUpdate(&ctx, A, A_len);
  49. EVP_MD_CTX_copy_ex(&ctx_tmp, &ctx);
  50. if(seed1 != NULL && seed1_len > 0){
  51. EVP_DigestSignUpdate(&ctx, seed1, seed1_len);
  52. }
  53. if(seed2 != NULL && seed2_len > 0){
  54. EVP_DigestSignUpdate(&ctx, seed2, seed2_len);
  55. }
  56. if(seed3 != NULL && seed3_len > 0){
  57. EVP_DigestSignUpdate(&ctx, seed3, seed3_len);
  58. }
  59. if(seed4 != NULL && seed4_len > 0){
  60. EVP_DigestSignUpdate(&ctx, seed4, seed4_len);
  61. }
  62. if(remaining > chunk){
  63. EVP_DigestSignFinal(&ctx, out, &len);
  64. out += len;
  65. remaining -= len;
  66. /* Next A value */
  67. EVP_DigestSignFinal(&ctx_tmp, A, &A_len);
  68. } else {
  69. EVP_DigestSignFinal(&ctx, A, &A_len);
  70. memcpy(out, A, remaining);
  71. remaining -= remaining;
  72. }
  73. }
  74. return 1;
  75. }