-
Notifications
You must be signed in to change notification settings - Fork 114
/
Copy pathoqs_test_signatures.c
131 lines (114 loc) · 4.69 KB
/
oqs_test_signatures.c
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
// SPDX-License-Identifier: Apache-2.0 AND MIT
#include <openssl/evp.h>
#include <openssl/provider.h>
#include "oqs/oqs.h"
#include "test_common.h"
static OSSL_LIB_CTX *libctx = NULL;
static char *modulename = NULL;
static char *configfile = NULL;
static char *cert = NULL;
static char *privkey = NULL;
static char *certsdir = NULL;
static char *srpvfile = NULL;
static char *tmpfilename = NULL;
// sign-and-hash must work with and without providing a digest algorithm
static int test_oqs_signatures(const char *sigalg_name) {
EVP_MD_CTX *mdctx = NULL;
EVP_PKEY_CTX *ctx = NULL;
EVP_PKEY *key = NULL;
const char msg[] = "The quick brown fox jumps over... you know what";
unsigned char *sig;
size_t siglen;
int testresult = 1;
if (!alg_is_enabled(sigalg_name)) {
printf("Not testing disabled algorithm %s.\n", sigalg_name);
return 1;
}
// test with built-in digest only if default provider is active:
// TBD revisit when hybrids are activated: They always need default
// provider
if (OSSL_PROVIDER_available(libctx, "default")) {
testresult &=
(ctx = EVP_PKEY_CTX_new_from_name(
libctx, sigalg_name, "provider=oqsprovider")) != NULL &&
EVP_PKEY_keygen_init(ctx) && EVP_PKEY_generate(ctx, &key) &&
(mdctx = EVP_MD_CTX_new()) != NULL &&
EVP_DigestSignInit_ex(mdctx, NULL, "SHA512", libctx, NULL, key,
NULL) &&
EVP_DigestSignUpdate(mdctx, msg, sizeof(msg)) &&
EVP_DigestSignFinal(mdctx, NULL, &siglen) &&
(sig = OPENSSL_malloc(siglen)) != NULL &&
EVP_DigestSignFinal(mdctx, sig, &siglen) &&
EVP_DigestVerifyInit_ex(mdctx, NULL, "SHA512", libctx, NULL, key,
NULL) &&
EVP_DigestVerifyUpdate(mdctx, msg, sizeof(msg)) &&
EVP_DigestVerifyFinal(mdctx, sig, siglen);
sig[0] = ~sig[0];
testresult &= EVP_DigestVerifyInit_ex(mdctx, NULL, "SHA512", libctx,
NULL, key, NULL) &&
EVP_DigestVerifyUpdate(mdctx, msg, sizeof(msg)) &&
!EVP_DigestVerifyFinal(mdctx, sig, siglen);
}
EVP_MD_CTX_free(mdctx);
EVP_PKEY_free(key);
EVP_PKEY_CTX_free(ctx);
OPENSSL_free(sig);
mdctx = NULL;
key = NULL;
// this test must work also with default provider inactive:
testresult &=
(ctx = EVP_PKEY_CTX_new_from_name(libctx, sigalg_name,
"provider=oqsprovider")) != NULL &&
EVP_PKEY_keygen_init(ctx) && EVP_PKEY_generate(ctx, &key) &&
(mdctx = EVP_MD_CTX_new()) != NULL &&
EVP_DigestSignInit_ex(mdctx, NULL, NULL, libctx, NULL, key, NULL) &&
EVP_DigestSignUpdate(mdctx, msg, sizeof(msg)) &&
EVP_DigestSignFinal(mdctx, NULL, &siglen) &&
(sig = OPENSSL_malloc(siglen)) != NULL &&
EVP_DigestSignFinal(mdctx, sig, &siglen) &&
EVP_DigestVerifyInit_ex(mdctx, NULL, NULL, libctx, NULL, key, NULL) &&
EVP_DigestVerifyUpdate(mdctx, msg, sizeof(msg)) &&
EVP_DigestVerifyFinal(mdctx, sig, siglen);
sig[0] = ~sig[0];
testresult &=
EVP_DigestVerifyInit_ex(mdctx, NULL, NULL, libctx, NULL, key, NULL) &&
EVP_DigestVerifyUpdate(mdctx, msg, sizeof(msg)) &&
!EVP_DigestVerifyFinal(mdctx, sig, siglen);
EVP_MD_CTX_free(mdctx);
EVP_PKEY_free(key);
EVP_PKEY_CTX_free(ctx);
OPENSSL_free(sig);
return testresult;
}
#define nelem(a) (sizeof(a) / sizeof((a)[0]))
int main(int argc, char *argv[]) {
size_t i;
int errcnt = 0, test = 0, query_nocache;
OSSL_PROVIDER *oqsprov = NULL;
const OSSL_ALGORITHM *sigalgs;
T((libctx = OSSL_LIB_CTX_new()) != NULL);
T(argc == 3);
modulename = argv[1];
configfile = argv[2];
load_oqs_provider(libctx, modulename, configfile);
oqsprov = OSSL_PROVIDER_load(libctx, modulename);
sigalgs = OSSL_PROVIDER_query_operation(oqsprov, OSSL_OP_SIGNATURE,
&query_nocache);
if (sigalgs) {
for (; sigalgs->algorithm_names != NULL; sigalgs++) {
if (test_oqs_signatures(sigalgs->algorithm_names)) {
fprintf(stderr,
cGREEN " Signature test succeeded: %s" cNORM "\n",
sigalgs->algorithm_names);
} else {
fprintf(stderr, cRED " Signature test failed: %s" cNORM "\n",
sigalgs->algorithm_names);
ERR_print_errors_fp(stderr);
errcnt++;
}
}
}
OSSL_LIB_CTX_free(libctx);
TEST_ASSERT(errcnt == 0)
return !test;
}