Skip to content

Commit 3d8b8bb

Browse files
JacobBarthelmehdgarske
authored andcommitted
simple example app benchmarking PKCS7 envelop encode/decode
1 parent d7f7fb9 commit 3d8b8bb

1 file changed

Lines changed: 363 additions & 0 deletions

File tree

Lines changed: 363 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,363 @@
1+
/* benchmark-streaming-envelop.c
2+
*
3+
* Copyright (C) 2006-2025 wolfSSL Inc.
4+
*
5+
* This file is part of wolfSSL. (formerly known as CyaSSL)
6+
*
7+
* wolfSSL is free software; you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation; either version 2 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* wolfSSL is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program; if not, write to the Free Software
19+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
20+
*/
21+
22+
#include <wolfssl/options.h>
23+
#include <wolfssl/wolfcrypt/pkcs7.h>
24+
#include <wolfssl/wolfcrypt/error-crypt.h>
25+
#include <wolfssl/wolfcrypt/wc_port.h>
26+
#include <wolfssl/wolfcrypt/logging.h>
27+
28+
#define USE_CERT_BUFFERS_2048
29+
#include <wolfssl/certs_test.h>
30+
31+
#include <stdio.h>
32+
#include <sys/time.h>
33+
34+
#define CONTENT_FILE_NAME "conent-benchmark.bin"
35+
#define ENCODED_FILE_NAME "test-stream-dec.p7b"
36+
#define TEST_STREAM_CHUNK_SIZE 1000
37+
38+
struct timeval startTime;
39+
40+
static void TimeLogStart(void)
41+
{
42+
gettimeofday(&startTime, NULL);
43+
}
44+
45+
46+
static double ToSeconds(struct timeval* in)
47+
{
48+
double ret = 0;
49+
if (in != NULL) {
50+
ret = (double)(in->tv_sec + (double)(in->tv_usec/1000000.0));
51+
}
52+
return ret;
53+
}
54+
55+
56+
static double GetMBs(double dataSz)
57+
{
58+
struct timeval currentTime;
59+
double seconds;
60+
double MBS;
61+
62+
gettimeofday(&currentTime, NULL);
63+
64+
seconds = ToSeconds(&currentTime) - ToSeconds(&startTime);
65+
MBS = dataSz / 1000000.0;
66+
67+
return MBS/seconds;
68+
}
69+
70+
int CreateContentFile(double contentSz)
71+
{
72+
FILE* f;
73+
double i;
74+
int ret = 0;
75+
76+
f = fopen(CONTENT_FILE_NAME, "wb");
77+
if (f == NULL) {
78+
printf("Unable to create conent file [%s]\n", CONTENT_FILE_NAME);
79+
ret = -1;
80+
}
81+
else {
82+
for (i = 0; i < contentSz;) {
83+
double sz = (contentSz - i < 1000)? contentSz -i : 1000;
84+
byte tmpBuffer[1000];
85+
int j;
86+
87+
for (j = 0; j < sz; j++) {
88+
tmpBuffer[j] = rand() % 256;
89+
}
90+
sz = fwrite(tmpBuffer, 1, sz, f);
91+
if (sz <= 0) {
92+
printf("Failed to write to content file\n");
93+
ret = -1;
94+
break;
95+
}
96+
i += sz;
97+
}
98+
fclose(f);
99+
}
100+
return ret;
101+
}
102+
103+
typedef struct BENCHMARK_IO {
104+
FILE* in;
105+
FILE* out;
106+
byte buf[TEST_STREAM_CHUNK_SIZE];
107+
} BENCHMARK_IO;
108+
109+
110+
static int GetContentCB(PKCS7* pkcs7, byte** content, void* ctx)
111+
{
112+
int ret = 0;
113+
BENCHMARK_IO* io = (BENCHMARK_IO*)ctx;
114+
115+
if (io != NULL) {
116+
ret = fread(io->buf, 1, TEST_STREAM_CHUNK_SIZE, io->in);
117+
if (ret > 0) {
118+
*content = io->buf;
119+
}
120+
}
121+
122+
(void)pkcs7;
123+
return ret;
124+
}
125+
126+
127+
static int StreamOutputCB(PKCS7* pkcs7, const byte* output, word32 outputSz,
128+
void* ctx)
129+
{
130+
int ret = 0;
131+
BENCHMARK_IO* io = (BENCHMARK_IO*)ctx;
132+
133+
if (io != NULL) {
134+
ret = fwrite(output, 1, outputSz, io->out);
135+
if (ret < 0) {
136+
printf("stream output write failed\n");
137+
ret = -1;
138+
}
139+
}
140+
141+
(void)pkcs7;
142+
return 0;
143+
}
144+
145+
146+
static int EncodePKCS7Bundle(double contentSz, WC_RNG* rng)
147+
{
148+
wc_PKCS7* pkcs7;
149+
double per;
150+
int ret = 0;
151+
BENCHMARK_IO io;
152+
byte aes256Key[] = {
153+
0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
154+
0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
155+
0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
156+
0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08
157+
};
158+
159+
printf("Creating an encoded bundle ... ");
160+
TimeLogStart();
161+
162+
pkcs7 = wc_PKCS7_New(NULL, 0);
163+
if (pkcs7 == NULL) {
164+
printf("Failed to create PKCS7 struct\n");
165+
ret = MEMORY_E;
166+
}
167+
168+
if (ret == 0) {
169+
ret = wc_PKCS7_InitWithCert(pkcs7, (byte*)client_cert_der_2048,
170+
sizeof_client_cert_der_2048);
171+
if (ret != 0) {
172+
printf("Failed to init with cert\n");
173+
}
174+
}
175+
176+
if (pkcs7 != NULL) {
177+
#ifdef ECC_TIMING_RESISTANT
178+
pkcs7->rng = rng;
179+
#endif
180+
181+
pkcs7->content = NULL; /* pulling content from callback */
182+
pkcs7->contentSz = contentSz;
183+
pkcs7->contentOID = DATA;
184+
pkcs7->encryptOID = AES256CBCb;
185+
pkcs7->encryptionKey = aes256Key;
186+
pkcs7->encryptionKeySz = sizeof(aes256Key);
187+
}
188+
189+
/* open the IO files to use */
190+
if (ret == 0) {
191+
io.in = fopen(CONTENT_FILE_NAME, "rb");
192+
io.out = fopen(ENCODED_FILE_NAME, "wb");
193+
if (io.in == NULL || io.out == NULL) {
194+
printf("Failed to open the IO files\n");
195+
ret = -1;
196+
}
197+
}
198+
199+
if (ret == 0) {
200+
ret = wc_PKCS7_SetStreamMode(pkcs7, 1, GetContentCB, StreamOutputCB,
201+
(void*)&io);
202+
if (ret != 0) {
203+
printf("Failed to set stream mode\n");
204+
}
205+
}
206+
207+
if (ret == 0) {
208+
ret = wc_PKCS7_EncodeEnvelopedData(pkcs7, NULL, 0);
209+
if (ret <= 0) {
210+
printf("Failed to encode enveloped data\n");
211+
}
212+
}
213+
wc_PKCS7_Free(pkcs7);
214+
215+
if (ret > 0) {
216+
per = GetMBs(ret);
217+
printf("%.2f MB/s", per);
218+
}
219+
printf(" : ret = %d\n", ret);
220+
return 0;
221+
}
222+
223+
224+
static int DecryptCB(wc_PKCS7* pkcs7,
225+
const byte* output, word32 outputSz, void* ctx) {
226+
FILE* out = (FILE*)ctx;
227+
228+
if (out == NULL) {
229+
return -1;
230+
}
231+
232+
/* printf("Decoded in %d bytes\n", outputSz);
233+
* for (word32 z = 0; z < outputSz; z++) printf("%02X", output[z]);
234+
* printf("\n");
235+
*/
236+
fwrite(output, 1, outputSz, out);
237+
238+
(void)pkcs7;
239+
return 0;
240+
}
241+
242+
static int DecodePKCS7Bundle(void)
243+
{
244+
wc_PKCS7* pkcs7 = NULL;
245+
double per;
246+
int ret = 0;
247+
FILE* f = NULL;
248+
FILE* out = NULL;
249+
double totalSz = 0;
250+
byte testStreamBuffer[TEST_STREAM_CHUNK_SIZE];
251+
int testStreamBufferSz = 0;
252+
253+
printf("Decoding PKCS7 bundle ... ");
254+
TimeLogStart();
255+
256+
257+
pkcs7 = wc_PKCS7_New(NULL, 0);
258+
if (pkcs7 == NULL) {
259+
ret = MEMORY_E;
260+
}
261+
262+
if (ret == 0) {
263+
ret = wc_PKCS7_InitWithCert(pkcs7, (byte*)client_cert_der_2048,
264+
sizeof_client_cert_der_2048);
265+
}
266+
267+
if (ret == 0) {
268+
ret = wc_PKCS7_SetKey(pkcs7, (byte*)client_key_der_2048,
269+
sizeof_client_key_der_2048);
270+
}
271+
272+
if (ret == 0) {
273+
out = fopen("benchmark-decrypted.bin", "wb");
274+
if (out == NULL) {
275+
printf("Unable to open decrypted data out file\n");
276+
ret = -1;
277+
}
278+
}
279+
280+
if (ret == 0) {
281+
ret = wc_PKCS7_SetStreamMode(pkcs7, 1, NULL, DecryptCB, (void*)out);
282+
}
283+
284+
if (ret == 0) {
285+
f = fopen(ENCODED_FILE_NAME, "rb");
286+
if (f == NULL) {
287+
printf("Unable to open encoded file\n");
288+
ret = -1;
289+
}
290+
}
291+
292+
if (ret == 0) {
293+
do {
294+
testStreamBufferSz = (int)XFREAD(testStreamBuffer, 1,
295+
sizeof(testStreamBuffer), f);
296+
297+
ret = wc_PKCS7_DecodeEnvelopedData(pkcs7, testStreamBuffer,
298+
testStreamBufferSz, NULL, 0);
299+
totalSz += testStreamBufferSz;
300+
} while (ret == WC_PKCS7_WANT_READ_E);
301+
}
302+
303+
/* success with decoding */
304+
if (ret >= 0) {
305+
ret = 0;
306+
}
307+
308+
if (f != NULL) {
309+
fclose(f);
310+
}
311+
if (out != NULL) {
312+
fclose(out);
313+
}
314+
315+
wc_PKCS7_Free(pkcs7);
316+
317+
if (ret == 0) {
318+
per = GetMBs(totalSz);
319+
printf("%.2f MB/s", per);
320+
}
321+
printf(" : ret = %d\n", ret);
322+
return ret;
323+
}
324+
325+
326+
int main(int argc, char** argv)
327+
{
328+
double contentSz = 10000;
329+
WC_RNG rng;
330+
int ret;
331+
332+
if (argc > 1) {
333+
contentSz = atof(argv[1]);
334+
}
335+
336+
ret = wolfCrypt_Init();
337+
if (ret != 0) {
338+
printf("Failed to init wolfCrypt\n");
339+
}
340+
wolfSSL_Debugging_ON();
341+
342+
if (ret == 0) {
343+
ret = wc_InitRng(&rng);
344+
}
345+
346+
if (ret == 0) {
347+
ret = CreateContentFile(contentSz);
348+
}
349+
350+
if (ret == 0) {
351+
ret = EncodePKCS7Bundle(contentSz, &rng);
352+
}
353+
354+
if (ret == 0) {
355+
ret = DecodePKCS7Bundle();
356+
}
357+
358+
wc_FreeRng(&rng);
359+
360+
wolfCrypt_Cleanup();
361+
return 0;
362+
}
363+

0 commit comments

Comments
 (0)