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