hcrypt_sa.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. /*
  2. * SRT - Secure, Reliable, Transport
  3. * Copyright (c) 2018 Haivision Systems Inc.
  4. *
  5. * This Source Code Form is subject to the terms of the Mozilla Public
  6. * License, v. 2.0. If a copy of the MPL was not distributed with this
  7. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  8. *
  9. */
  10. /*****************************************************************************
  11. written by
  12. Haivision Systems Inc.
  13. 2011-06-23 (jdube)
  14. HaiCrypt initial implementation.
  15. *****************************************************************************/
  16. /*
  17. * For now:
  18. * Pre-shared or password derived KEK (Key Encrypting Key)
  19. * Future:
  20. * Certificate-based association
  21. */
  22. #include <string.h> /* memcpy */
  23. #include "hcrypt.h"
  24. int hcryptCtx_SetSecret(hcrypt_Session *crypto, hcrypt_Ctx *ctx, const HaiCrypt_Secret *secret)
  25. {
  26. int iret;
  27. (void)crypto;
  28. switch(secret->typ) {
  29. case HAICRYPT_SECTYP_PRESHARED:
  30. ASSERT(secret->len <= HAICRYPT_KEY_MAX_SZ);
  31. ctx->cfg.pwd_len = 0;
  32. /* KEK: Key Encrypting Key */
  33. if (0 > (iret = crypto->cryspr->km_setkey(crypto->cryspr_cb,
  34. ((HCRYPT_CTX_F_ENCRYPT & ctx->flags) ? true : false),
  35. secret->str, secret->len))) {
  36. HCRYPT_LOG(LOG_ERR, "km_setkey(pdkek[%zd]) failed (rc=%d)\n", secret->len, iret);
  37. return(-1);
  38. }
  39. ctx->status = HCRYPT_CTX_S_SARDY;
  40. break;
  41. case HAICRYPT_SECTYP_PASSPHRASE:
  42. ASSERT(secret->len <= sizeof(ctx->cfg.pwd));
  43. memcpy(ctx->cfg.pwd, secret->str, secret->len);
  44. ctx->cfg.pwd_len = secret->len;
  45. /* KEK will be derived from password with Salt */
  46. ctx->status = HCRYPT_CTX_S_SARDY;
  47. break;
  48. default:
  49. HCRYPT_LOG(LOG_ERR, "Unknown secret type %d\n",
  50. secret->typ);
  51. return(-1);
  52. }
  53. return(0);
  54. }
  55. int hcryptCtx_GenSecret(hcrypt_Session *crypto, hcrypt_Ctx *ctx)
  56. {
  57. /*
  58. * KEK need same length as the key it protects (SEK)
  59. * KEK = PBKDF2(Pwd, LSB(64, Salt), Iter, Klen)
  60. */
  61. unsigned char kek[HAICRYPT_KEY_MAX_SZ];
  62. size_t kek_len = ctx->sek_len;
  63. size_t pbkdf_salt_len = (ctx->salt_len >= HAICRYPT_PBKDF2_SALT_LEN
  64. ? HAICRYPT_PBKDF2_SALT_LEN
  65. : ctx->salt_len);
  66. int iret = 0;
  67. (void)crypto;
  68. iret = crypto->cryspr->km_pbkdf2(crypto->cryspr_cb, ctx->cfg.pwd, ctx->cfg.pwd_len,
  69. &ctx->salt[ctx->salt_len - pbkdf_salt_len], pbkdf_salt_len,
  70. HAICRYPT_PBKDF2_ITER_CNT, kek_len, kek);
  71. if(iret) {
  72. HCRYPT_LOG(LOG_ERR, "km_pbkdf2() failed (rc=%d)\n", iret);
  73. return(-1);
  74. }
  75. HCRYPT_PRINTKEY(ctx->cfg.pwd, ctx->cfg.pwd_len, "pwd");
  76. HCRYPT_PRINTKEY(kek, kek_len, "kek");
  77. /* KEK: Key Encrypting Key */
  78. if (0 > (iret = crypto->cryspr->km_setkey(crypto->cryspr_cb, ((HCRYPT_CTX_F_ENCRYPT & ctx->flags) ? true : false), kek, kek_len))) {
  79. HCRYPT_LOG(LOG_ERR, "km_setkey(pdkek[%zd]) failed (rc=%d)\n", kek_len, iret);
  80. return(-1);
  81. }
  82. return(0);
  83. }