hcrypt_tx.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  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 <sys/types.h>
  19. #include <stdlib.h> /* NULL */
  20. #include <string.h> /* memcpy */
  21. #ifdef _WIN32
  22. #include <winsock2.h>
  23. #include <ws2tcpip.h>
  24. #include <stdint.h>
  25. #else
  26. #include <arpa/inet.h> /* htonl */
  27. #endif
  28. #include "hcrypt.h"
  29. int HaiCrypt_Tx_GetBuf(HaiCrypt_Handle hhc, size_t data_len, unsigned char **in_pp)
  30. {
  31. hcrypt_Session *crypto = (hcrypt_Session *)hhc;
  32. ASSERT(NULL != crypto);
  33. ASSERT(NULL != crypto->cryspr);
  34. int pad_factor = (HCRYPT_CTX_MODE_AESECB == crypto->ctx->mode ? 128/8 : 1);
  35. #ifndef _WIN32
  36. ASSERT(crypto->inbuf != NULL);
  37. #endif
  38. size_t in_len = crypto->msg_info->pfx_len + hcryptMsg_PaddedLen(data_len, pad_factor);
  39. *in_pp = crypto->inbuf;
  40. if (in_len > crypto->inbuf_siz) {
  41. *in_pp = NULL;
  42. return(-1);
  43. }
  44. return(crypto->msg_info->pfx_len);
  45. }
  46. int HaiCrypt_Tx_ManageKeys(HaiCrypt_Handle hhc, void *out_p[], size_t out_len_p[], int maxout)
  47. {
  48. hcrypt_Session *crypto = (hcrypt_Session *)hhc;
  49. int nbout = 0;
  50. if ((NULL == crypto)
  51. || (NULL == crypto->ctx)
  52. || (NULL == out_p)
  53. || (NULL == out_len_p)) {
  54. HCRYPT_LOG(LOG_ERR, "ManageKeys: invalid params: crypto=%p out_p=%p out_len_p=%p\n",
  55. crypto, out_p, out_len_p);
  56. return(-1);
  57. }
  58. /* Manage Key Material (refresh, announce, decommission) */
  59. hcryptCtx_Tx_ManageKM(crypto);
  60. if (NULL == crypto->ctx) {
  61. HCRYPT_LOG(LOG_ERR, "%s", "crypto context NULL after ManageKM call\n");
  62. return(-1);
  63. }
  64. ASSERT(crypto->ctx->status == HCRYPT_CTX_S_ACTIVE);
  65. nbout = hcryptCtx_Tx_InjectKM(crypto, out_p, out_len_p, maxout);
  66. return(nbout);
  67. }
  68. int HaiCrypt_Tx_GetKeyFlags(HaiCrypt_Handle hhc)
  69. {
  70. hcrypt_Session *crypto = (hcrypt_Session *)hhc;
  71. hcrypt_Ctx *ctx = NULL;
  72. if ((NULL == crypto)
  73. || (NULL == (ctx = crypto->ctx))) {
  74. HCRYPT_LOG(LOG_ERR, "GetKeyFlags: invalid params: crypto=%p crypto->ctx=%p\n", crypto, ctx);
  75. return(-1);
  76. }
  77. return(hcryptCtx_GetKeyFlags(crypto->ctx));
  78. }
  79. int HaiCrypt_Tx_Data(HaiCrypt_Handle hhc,
  80. unsigned char *in_pfx, unsigned char *in_data, size_t in_len)
  81. {
  82. hcrypt_Session *crypto = (hcrypt_Session *)hhc;
  83. hcrypt_Ctx *ctx = NULL;
  84. int nbout = 0;
  85. if ((NULL == crypto)
  86. || (NULL == (ctx = crypto->ctx))) {
  87. HCRYPT_LOG(LOG_ERR, "Tx_Data: invalid params: crypto=%p crypto->ctx=%p\n", crypto, ctx);
  88. return(-1);
  89. }
  90. /* Get/Set packet index */
  91. ctx->msg_info->indexMsg(in_pfx, ctx->MSpfx_cache);
  92. if (hcryptMsg_GetKeyIndex(ctx->msg_info, in_pfx) != hcryptCtx_GetKeyIndex(ctx))
  93. {
  94. HCRYPT_LOG(LOG_ERR, "Tx_Data: Key mismatch!");
  95. }
  96. /* Encrypt */
  97. {
  98. hcrypt_DataDesc indata;
  99. indata.pfx = in_pfx;
  100. indata.payload = in_data;
  101. indata.len = in_len;
  102. if (0 > (nbout = crypto->cryspr->ms_encrypt(crypto->cryspr_cb, ctx, &indata, 1, NULL, NULL, NULL))) {
  103. HCRYPT_LOG(LOG_ERR, "%s", "ms_encrypt failed\n");
  104. return(nbout);
  105. }
  106. }
  107. ctx->pkt_cnt++;
  108. return(nbout);
  109. }
  110. int HaiCrypt_Tx_Process(HaiCrypt_Handle hhc,
  111. unsigned char *in_msg, size_t in_len,
  112. void *out_p[], size_t out_len_p[], int maxout)
  113. {
  114. hcrypt_Session *crypto = (hcrypt_Session *)hhc;
  115. hcrypt_Ctx *ctx = NULL;
  116. int nb, nbout = 0;
  117. if ((NULL == crypto)
  118. || (NULL == (ctx = crypto->ctx))
  119. || (NULL == out_p)
  120. || (NULL == out_len_p)) {
  121. HCRYPT_LOG(LOG_ERR, "Tx_Process: invalid params: crypto=%p crypto->ctx=%p\n", crypto, ctx);
  122. return(-1);
  123. }
  124. /* Manage Key Material (refresh, announce, decommission) */
  125. hcryptCtx_Tx_ManageKM(crypto);
  126. ASSERT(ctx->status == HCRYPT_CTX_S_ACTIVE);
  127. nbout += hcryptCtx_Tx_InjectKM(crypto, out_p, out_len_p, maxout);
  128. /* Get packet index */
  129. ctx->msg_info->indexMsg(in_msg, ctx->MSpfx_cache);
  130. /* Encrypt */
  131. nb = maxout - nbout;
  132. {
  133. hcrypt_DataDesc indata;
  134. indata.pfx = in_msg;
  135. indata.payload = &in_msg[ctx->msg_info->pfx_len];
  136. indata.len = in_len - ctx->msg_info->pfx_len;
  137. if (crypto->cryspr->ms_encrypt(crypto->cryspr_cb, ctx, &indata, 1, &out_p[nbout], &out_len_p[nbout], &nb)) {
  138. HCRYPT_LOG(LOG_ERR, "%s", "ms_encrypt failed\n");
  139. return(nbout);
  140. }
  141. }
  142. nbout += nb;
  143. ctx->pkt_cnt++;
  144. return(nbout);
  145. }