1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
/*
* SRT - Secure, Reliable, Transport
* Copyright (c) 2019 Haivision Systems Inc.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
/*****************************************************************************
written by
Haivision Systems Inc.
2019-06-28 (jdube)
CRYSPR/4SRT Initial implementation.
*****************************************************************************/
#ifndef CRYSPR_H
#define CRYSPR_H
#include <stdbool.h>
#include <sys/types.h>
#if !defined(HAISRT_VERSION_INT)
#include "haicrypt.h"
#include "hcrypt_msg.h"
#else
// Included by haisrt.h or similar
#include "haisrt/haicrypt.h"
#include "haisrt/hcrypt_msg.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
#include "cryspr-config.h"
typedef struct tag_CRYSPR_cb {
CRYSPR_AESCTX aes_kek; /* Key Encrypting Key (KEK) */
CRYSPR_AESCTX aes_sek[2]; /* even/odd Stream Encrypting Key (SEK) */
struct tag_CRYSPR_methods *cryspr;
#if !CRYSPR_HAS_AESCTR
/* Reserve room to build the counter stream ourself */
#define HCRYPT_CTR_BLK_SZ CRYSPR_AESBLKSZ
#define HCRYPT_CTR_STREAM_SZ 2048
unsigned char * ctr_stream;
size_t ctr_stream_len; /* Content size */
size_t ctr_stream_siz; /* Allocated length */
#endif /* !CRYSPR_HAS_AESCTR */
#define CRYSPR_OUTMSGMAX 6
uint8_t * outbuf; /* output circle buffer */
size_t outbuf_ofs; /* write offset in circle buffer */
size_t outbuf_siz; /* circle buffer size */
} CRYSPR_cb;
typedef struct tag_CRYSPR_methods {
/*
* prng:
* Pseudo-Random Number Generator
*/
int (*prng)(
unsigned char *rn, /* out: pseudo random number */
int rn_len);
int (*aes_set_key)(
bool bEncrypt, /* true Enxcrypt key, false: decrypt */
const unsigned char *kstr,/* key string*/
size_t kstr_len, /* kstr len in bytes (16, 24, or 32 bytes (for AES128,AES192, or AES256) */
CRYSPR_AESCTX *aeskey); /* Cryptolib Specific AES key context */
int (*aes_ecb_cipher)(
bool bEncrypt, /* true:encrypt false:decrypt */
CRYSPR_AESCTX *aes_key, /* ctx */
const unsigned char *indata, /* src (clear text)*/
size_t inlen, /* src length */
unsigned char *out_txt, /* dst (cipher text) */
size_t *outlen); /* dst length */
int (*aes_ctr_cipher)(
bool bEncrypt, /* true:encrypt false:decrypt (don't care with CTR) */
CRYSPR_AESCTX *aes_key, /* ctx */
unsigned char *iv, /* iv */
const unsigned char *indata, /* src (clear text) */
size_t inlen, /* src length */
unsigned char *out_txt);/* dest */
unsigned char *(*sha1_msg_digest)(
const unsigned char *m, /* in: message */
size_t m_len, /* message length */
unsigned char *md); /* out: message digest buffer *160 bytes */
/*
* open:
* Create a cipher instance
* Allocate output buffers
*/
CRYSPR_cb *(*open)(
struct tag_CRYSPR_methods *cryspr,
size_t max_len); /* Maximum packet length that will be encrypted/decrypted */
/*
* close:
* Release any cipher resources
*/
int (*close)(
CRYSPR_cb *cryspr_data); /* Cipher handle, internal data */
/*
* pbkdf2_hmac_sha1
* Password-based Key Derivation Function 2
*/
int (*km_pbkdf2)(
CRYSPR_cb *cryspr_cb, /* Cryspr Control Block */
char *passwd, /* passphrase */
size_t passwd_len, /* passphrase len */
unsigned char *salt, /* salt */
size_t salt_len, /* salt_len */
int itr, /* iterations */
size_t out_len, /* key_len */
unsigned char *out); /* derived key */
/*
* km_setkey:
* Set the Key Encypting Key for Wrap (Encryption) or UnWrap (Decryption).
* Context (ctx) tells if it's for Wrap or Unwrap
* A Context flags (ctx->flags) also tells if this is for wrap(encryption) or unwrap(decryption) context (HCRYPT_CTX_F_ENCRYPT)
*/
int (*km_setkey)(
CRYSPR_cb *cryspr_cb, /* Cryspr Control Block */
bool bWrap, /* True: Wrap KEK, False: Unwrap KEK */
const unsigned char *kek, size_t kek_len); /* KEK: Key Encrypting Key */
/*
* km_wrap:
* wrap media stream key
*/
int (*km_wrap)(CRYSPR_cb *cryspr_cb,
unsigned char *wrap,
const unsigned char *sek,
unsigned int seklen);
/*
* km_unwrap:
* wrap media stream key
*/
int (*km_unwrap)(CRYSPR_cb *cryspr_cb,
unsigned char *sek,
const unsigned char *wrap,
unsigned int wraplen);
/*
* setkey:
* Set the Odd or Even, Encryption or Decryption key.
* Context (ctx) tells if it's for Odd or Even key (hcryptCtx_GetKeyIndex(ctx))
* A Context flags (ctx->flags) also tells if this is an encryption or decryption context (HCRYPT_CTX_F_ENCRYPT)
*/
int (*ms_setkey)(
CRYSPR_cb *cryspr_cb, /* Cryspr Control Block */
hcrypt_Ctx *ctx, /* HaiCrypt Context (cipher, keys, Odd/Even, etc..) */
const unsigned char *key, size_t kwelen); /* New Key */
/*
* encrypt:
* Submit a list of nbin clear transport packets (hcrypt_DataDesc *in_data) to encryption
* returns *nbout encrypted data packets of length out_len_p[] into out_p[]
*
* If cipher implements deferred encryption (co-processor, async encryption),
* it may return no encrypted packets, or encrypted packets for clear text packets of a previous call.
*/
int (*ms_encrypt)(
CRYSPR_cb *cryspr_cb, /* Cryspr Control Block */
hcrypt_Ctx *ctx, /* HaiCrypt Context (cipher, keys, Odd/Even, etc..) */
hcrypt_DataDesc *in_data, int nbin, /* Clear text transport packets: header and payload */
void *out_p[], size_t out_len_p[], int *nbout); /* Encrypted packets */
/*
* decrypt:
* Submit a list of nbin encrypted transport packets (hcrypt_DataDesc *in_data) to decryption
* returns *nbout clear text data packets of length out_len_p[] into out_p[]
*
* If cipher implements deferred decryption (co-processor, async encryption),
* it may return no decrypted packets, or decrypted packets for encrypted packets of a previous call.
*/
int (*ms_decrypt)(
CRYSPR_cb *cryspr_cb, /* Cryspr Control Block */
hcrypt_Ctx *ctx, /* HaiCrypt Context (cipher, keys, Odd/Even, etc..) */
hcrypt_DataDesc *in_data, int nbin, /* Clear text transport packets: header and payload */
void *out_p[], size_t out_len_p[], int *nbout); /* Encrypted packets */
} CRYSPR_methods;
CRYSPR_methods *crysprInit(CRYSPR_methods *cryspr);
#ifdef __cplusplus
}
#endif
#endif /* CRYSPR_H */