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