2
0

hcrypt_xpt_srt.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  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. 2014-03-11 (jdube)
  14. Adaptation for SRT.
  15. *****************************************************************************/
  16. #include <string.h> /* memset, memcpy */
  17. #ifdef _WIN32
  18. #include <winsock2.h>
  19. #include <ws2tcpip.h>
  20. #else
  21. #include <arpa/inet.h> /* htonl, ntohl */
  22. #endif
  23. #include "hcrypt.h"
  24. /*
  25. * HaiCrypt SRT (Secure Reliable Transport) Media Stream (MS) Msg Prefix:
  26. * This is UDT data header with Crypto Key Flags (KF) added.
  27. * Header is in 32bit host order words in the context of the functions of this handler.
  28. *
  29. * 0 1 2 3
  30. * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  31. * +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
  32. * 0x00 |0| Packet Sequence Number (pki) |
  33. * +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
  34. * 0x04 |FF |o|KF | Message Number |
  35. * +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
  36. * 0x08 | Time Stamp |
  37. * +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
  38. * 0x0C | Destination Socket ID) |
  39. * +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
  40. * | Payload... |
  41. */
  42. /*
  43. * HaiCrypt Standalone Transport Keying Material (KM) Msg header kept in SRT
  44. * Message and cache maintained in network order
  45. *
  46. * 0 1 2 3
  47. * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  48. * +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
  49. * 0x00 |0|Vers | PT | Sign | resv |
  50. * +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
  51. * ... .
  52. */
  53. #define HCRYPT_MSG_SRT_HDR_SZ 16
  54. #define HCRYPT_MSG_SRT_PFX_SZ 16
  55. #define HCRYPT_MSG_SRT_OFS_PKI 0
  56. #define HCRYPT_MSG_SRT_OFS_MSGNO 4
  57. #define HCRYPT_MSG_SRT_SHF_KFLGS 27 //shift
  58. static hcrypt_MsgInfo _hcMsg_SRT_MsgInfo;
  59. static unsigned hcryptMsg_SRT_GetKeyFlags(unsigned char *msg)
  60. {
  61. uint32_t msgno;
  62. memcpy(&msgno, &msg[HCRYPT_MSG_SRT_OFS_MSGNO], sizeof(msgno)); //header is in host order
  63. return((unsigned)((msgno >> HCRYPT_MSG_SRT_SHF_KFLGS) & HCRYPT_MSG_F_xSEK));
  64. }
  65. static hcrypt_Pki hcryptMsg_SRT_GetPki(unsigned char *msg, int nwkorder)
  66. {
  67. hcrypt_Pki pki;
  68. memcpy(&pki, &msg[HCRYPT_MSG_SRT_OFS_PKI], sizeof(pki)); //header is in host order
  69. return (nwkorder ? htonl(pki) : pki);
  70. }
  71. static void hcryptMsg_SRT_SetPki(unsigned char *msg, hcrypt_Pki pki)
  72. {
  73. memcpy(&msg[HCRYPT_MSG_SRT_OFS_PKI], &pki, sizeof(pki)); //header is in host order
  74. }
  75. static void hcryptMsg_SRT_ResetCache(unsigned char *pfx_cache, unsigned pkt_type, unsigned kflgs)
  76. {
  77. switch(pkt_type) {
  78. case HCRYPT_MSG_PT_MS: /* Media Stream */
  79. /* Nothing to do, header filled by protocol */
  80. break;
  81. case HCRYPT_MSG_PT_KM: /* Keying Material */
  82. pfx_cache[HCRYPT_MSG_KM_OFS_VERSION] = (unsigned char)((HCRYPT_MSG_VERSION << 4) | pkt_type); // version || PT
  83. pfx_cache[HCRYPT_MSG_KM_OFS_SIGN] = (unsigned char)((HCRYPT_MSG_SIGN >> 8) & 0xFF); // Haivision PnP Mfr ID
  84. pfx_cache[HCRYPT_MSG_KM_OFS_SIGN+1] = (unsigned char)(HCRYPT_MSG_SIGN & 0xFF);
  85. pfx_cache[HCRYPT_MSG_KM_OFS_KFLGS] = (unsigned char)kflgs; //HCRYPT_MSG_F_xxx
  86. break;
  87. default:
  88. break;
  89. }
  90. }
  91. static void hcryptMsg_SRT_IndexMsg(unsigned char *msg, unsigned char *pfx_cache)
  92. {
  93. (void)msg;
  94. (void)pfx_cache;
  95. return; //nothing to do, header and index maintained by SRT
  96. }
  97. static int hcryptMsg_SRT_ParseMsg(unsigned char *msg)
  98. {
  99. int rc;
  100. if ((HCRYPT_MSG_VERSION == hcryptMsg_KM_GetVersion(msg)) /* Version 1 */
  101. && (HCRYPT_MSG_PT_KM == hcryptMsg_KM_GetPktType(msg)) /* Keying Material */
  102. && (HCRYPT_MSG_SIGN == hcryptMsg_KM_GetSign(msg))) { /* 'HAI' PnP Mfr ID */
  103. rc = HCRYPT_MSG_PT_KM;
  104. } else {
  105. //Assume it's data.
  106. //SRT does not call this for MS msg
  107. rc = HCRYPT_MSG_PT_MS;
  108. }
  109. switch(rc) {
  110. case HCRYPT_MSG_PT_MS:
  111. if (hcryptMsg_HasNoSek(&_hcMsg_SRT_MsgInfo, msg)
  112. || hcryptMsg_HasBothSek(&_hcMsg_SRT_MsgInfo, msg)) {
  113. HCRYPT_LOG(LOG_ERR, "invalid MS msg flgs: %02x\n",
  114. hcryptMsg_GetKeyIndex(&_hcMsg_SRT_MsgInfo, msg));
  115. return(-1);
  116. }
  117. break;
  118. case HCRYPT_MSG_PT_KM:
  119. if (HCRYPT_SE_TSSRT != hcryptMsg_KM_GetSE(msg)) { //Check Stream Encapsulation (SE)
  120. HCRYPT_LOG(LOG_ERR, "invalid KM msg SE: %d\n",
  121. hcryptMsg_KM_GetSE(msg));
  122. return(-1);
  123. }
  124. if (hcryptMsg_KM_HasNoSek(msg)) {
  125. HCRYPT_LOG(LOG_ERR, "invalid KM msg flgs: %02x\n",
  126. hcryptMsg_KM_GetKeyIndex(msg));
  127. return(-1);
  128. }
  129. break;
  130. default:
  131. HCRYPT_LOG(LOG_ERR, "invalid pkt type: %d\n", rc);
  132. rc = 0; /* unknown packet type */
  133. break;
  134. }
  135. return(rc); /* -1: error, 0: unknown: >0: PT */
  136. }
  137. static hcrypt_MsgInfo _hcMsg_SRT_MsgInfo;
  138. hcrypt_MsgInfo *hcryptMsg_SRT_MsgInfo(void)
  139. {
  140. _hcMsg_SRT_MsgInfo.hdr_len = HCRYPT_MSG_SRT_HDR_SZ;
  141. _hcMsg_SRT_MsgInfo.pfx_len = HCRYPT_MSG_SRT_PFX_SZ;
  142. _hcMsg_SRT_MsgInfo.getKeyFlags = hcryptMsg_SRT_GetKeyFlags;
  143. _hcMsg_SRT_MsgInfo.getPki = hcryptMsg_SRT_GetPki;
  144. _hcMsg_SRT_MsgInfo.setPki = hcryptMsg_SRT_SetPki;
  145. _hcMsg_SRT_MsgInfo.resetCache = hcryptMsg_SRT_ResetCache;
  146. _hcMsg_SRT_MsgInfo.indexMsg = hcryptMsg_SRT_IndexMsg;
  147. _hcMsg_SRT_MsgInfo.parseMsg = hcryptMsg_SRT_ParseMsg;
  148. return(&_hcMsg_SRT_MsgInfo);
  149. }