2
0

hcrypt_rx.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  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. 2014-03-11 (jdube)
  16. Adaptation for SRT.
  17. *****************************************************************************/
  18. #include <stdlib.h> /* NULL */
  19. #include <string.h> /* memcmp */
  20. #include "hcrypt.h"
  21. int HaiCrypt_Rx_Data(HaiCrypt_Handle hhc,
  22. unsigned char *in_pfx, unsigned char *data, size_t data_len)
  23. {
  24. hcrypt_Session *crypto = (hcrypt_Session *)hhc;
  25. hcrypt_Ctx *ctx;
  26. int nb = -1;
  27. if ((NULL == crypto)
  28. || (NULL == data)) {
  29. HCRYPT_LOG(LOG_ERR, "%s", "invalid parameters\n");
  30. return(nb);
  31. }
  32. ctx = &crypto->ctx_pair[hcryptMsg_GetKeyIndex(crypto->msg_info, in_pfx)];
  33. ASSERT(NULL != ctx); /* Header check should prevent this error */
  34. ASSERT(NULL != crypto->cryspr); /* Header check should prevent this error */
  35. crypto->ctx = ctx; /* Context of last received msg */
  36. if (NULL == crypto->cryspr->ms_decrypt) {
  37. HCRYPT_LOG(LOG_ERR, "%s", "cryspr had no decryptor\n");
  38. } else if (ctx->status >= HCRYPT_CTX_S_KEYED) {
  39. hcrypt_DataDesc indata;
  40. indata.pfx = in_pfx;
  41. indata.payload = data;
  42. indata.len = data_len;
  43. if (0 > (nb = crypto->cryspr->ms_decrypt(crypto->cryspr_cb, ctx, &indata, 1, NULL, NULL, NULL))) {
  44. HCRYPT_LOG(LOG_ERR, "%s", "ms_decrypt failed\n");
  45. } else {
  46. nb = (int)indata.len;
  47. }
  48. } else { /* No key received yet */
  49. nb = 0;
  50. }
  51. return(nb);
  52. }
  53. int HaiCrypt_Rx_Process(HaiCrypt_Handle hhc,
  54. unsigned char *in_msg, size_t in_len,
  55. void *out_p[], size_t out_len_p[], int maxout)
  56. {
  57. hcrypt_Session *crypto = (hcrypt_Session *)hhc;
  58. hcrypt_Ctx *ctx;
  59. int nbout = maxout;
  60. int msg_type;
  61. if ((NULL == crypto)
  62. || (NULL == in_msg)) {
  63. HCRYPT_LOG(LOG_ERR, "%s", "invalid parameters\n");
  64. return(-1);
  65. }
  66. /* Validate HaiCrypt message */
  67. if (0 > (msg_type = crypto->msg_info->parseMsg(in_msg))) {
  68. return(-1);
  69. }
  70. switch(msg_type) {
  71. case HCRYPT_MSG_PT_MS: /* MSmsg */
  72. ctx = &crypto->ctx_pair[hcryptMsg_GetKeyIndex(crypto->msg_info, in_msg)];
  73. if ((NULL == out_p)
  74. || (NULL == out_len_p)) {
  75. HCRYPT_LOG(LOG_ERR, "%s", "invalid parameters\n");
  76. return(-1);
  77. }
  78. ASSERT(NULL != ctx); /* Header check should prevent this error */
  79. ASSERT(NULL != crypto->cryspr); /* Header check should prevent this error */
  80. crypto->ctx = ctx; /* Context of last received msg */
  81. if (NULL == crypto->cryspr->ms_decrypt) {
  82. HCRYPT_LOG(LOG_ERR, "%s", "cryspr had no decryptor\n");
  83. nbout = -1;
  84. } else if (ctx->status >= HCRYPT_CTX_S_KEYED) {
  85. hcrypt_DataDesc indata;
  86. indata.pfx = in_msg;
  87. indata.payload = &in_msg[crypto->msg_info->pfx_len];
  88. indata.len = in_len - crypto->msg_info->pfx_len;
  89. if (crypto->cryspr->ms_decrypt(crypto->cryspr_cb, ctx, &indata, 1, out_p, out_len_p, &nbout)) {
  90. HCRYPT_LOG(LOG_ERR, "%s", "ms_decrypt failed\n");
  91. nbout = -1;
  92. }
  93. } else { /* No key received yet */
  94. nbout = 0;
  95. }
  96. break;
  97. case HCRYPT_MSG_PT_KM: /* KMmsg */
  98. /* Even or Both SEKs check with even context */
  99. ctx = &crypto->ctx_pair[hcryptMsg_GetKeyIndex(crypto->msg_info, in_msg)];
  100. ASSERT(NULL != ctx); /* Header check should prevent this error */
  101. if ((ctx->status < HCRYPT_CTX_S_KEYED) /* No key deciphered yet */
  102. || (in_len != ctx->KMmsg_len) /* or not same size */
  103. || (0 != memcmp(ctx->KMmsg_cache, in_msg, in_len))) { /* or different */
  104. nbout = hcryptCtx_Rx_ParseKM(crypto, in_msg, in_len);
  105. } else {
  106. nbout = 0;
  107. }
  108. if (NULL != out_p) out_p[0] = NULL;
  109. if (NULL != out_len_p) out_len_p[0] = 0;
  110. break;
  111. default:
  112. HCRYPT_LOG(LOG_WARNING, "%s", "unknown packet type\n");
  113. nbout = 0;
  114. break;
  115. }
  116. return(nbout);
  117. }