]>
Commit | Line | Data |
---|---|---|
36fc5fc6 | 1 | /* |
47c239c6 | 2 | * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. |
36fc5fc6 SL |
3 | * |
4 | * Licensed under the Apache License 2.0 (the "License"). You may not use | |
5 | * this file except in compliance with the License. You can obtain a copy | |
6 | * in the file LICENSE in the source distribution or at | |
7 | * https://www.openssl.org/source/license.html | |
8 | */ | |
9 | ||
10 | #include <openssl/self_test.h> | |
47c239c6 SL |
11 | #include <openssl/core_names.h> |
12 | #include <openssl/params.h> | |
36fc5fc6 SL |
13 | #include "internal/cryptlib.h" |
14 | ||
15 | typedef struct self_test_cb_st | |
16 | { | |
17 | OSSL_CALLBACK *cb; | |
18 | void *cbarg; | |
19 | } SELF_TEST_CB; | |
20 | ||
47c239c6 SL |
21 | struct ossl_self_test_st |
22 | { | |
23 | /* local state variables */ | |
24 | const char *phase; | |
25 | const char *type; | |
26 | const char *desc; | |
27 | OSSL_CALLBACK *cb; | |
28 | ||
29 | /* callback related variables used to pass the state back to the user */ | |
30 | OSSL_PARAM params[4]; | |
31 | void *cb_arg; | |
32 | }; | |
33 | ||
f8e74747 | 34 | #ifndef FIPS_MODULE |
b4250010 | 35 | static void *self_test_set_callback_new(OSSL_LIB_CTX *ctx) |
36fc5fc6 SL |
36 | { |
37 | SELF_TEST_CB *stcb; | |
38 | ||
39 | stcb = OPENSSL_zalloc(sizeof(*stcb)); | |
40 | return stcb; | |
41 | } | |
42 | ||
43 | static void self_test_set_callback_free(void *stcb) | |
44 | { | |
45 | OPENSSL_free(stcb); | |
46 | } | |
47 | ||
b4250010 | 48 | static const OSSL_LIB_CTX_METHOD self_test_set_callback_method = { |
36fc5fc6 SL |
49 | self_test_set_callback_new, |
50 | self_test_set_callback_free, | |
51 | }; | |
52 | ||
b4250010 | 53 | static SELF_TEST_CB *get_self_test_callback(OSSL_LIB_CTX *libctx) |
36fc5fc6 | 54 | { |
b4250010 DMSP |
55 | return ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_SELF_TEST_CB_INDEX, |
56 | &self_test_set_callback_method); | |
36fc5fc6 SL |
57 | } |
58 | ||
b4250010 | 59 | void OSSL_SELF_TEST_set_callback(OSSL_LIB_CTX *libctx, OSSL_CALLBACK *cb, |
36fc5fc6 SL |
60 | void *cbarg) |
61 | { | |
62 | SELF_TEST_CB *stcb = get_self_test_callback(libctx); | |
63 | ||
64 | if (stcb != NULL) { | |
65 | stcb->cb = cb; | |
66 | stcb->cbarg = cbarg; | |
67 | } | |
68 | } | |
47c239c6 | 69 | |
b4250010 | 70 | void OSSL_SELF_TEST_get_callback(OSSL_LIB_CTX *libctx, OSSL_CALLBACK **cb, |
36fc5fc6 SL |
71 | void **cbarg) |
72 | { | |
73 | SELF_TEST_CB *stcb = get_self_test_callback(libctx); | |
74 | ||
75 | if (cb != NULL) | |
76 | *cb = (stcb != NULL ? stcb->cb : NULL); | |
77 | if (cbarg != NULL) | |
78 | *cbarg = (stcb != NULL ? stcb->cbarg : NULL); | |
79 | } | |
f8e74747 | 80 | #endif /* FIPS_MODULE */ |
47c239c6 SL |
81 | |
82 | static void self_test_setparams(OSSL_SELF_TEST *st) | |
83 | { | |
84 | size_t n = 0; | |
85 | ||
86 | if (st->cb != NULL) { | |
87 | st->params[n++] = | |
88 | OSSL_PARAM_construct_utf8_string(OSSL_PROV_PARAM_SELF_TEST_PHASE, | |
89 | (char *)st->phase, 0); | |
90 | st->params[n++] = | |
91 | OSSL_PARAM_construct_utf8_string(OSSL_PROV_PARAM_SELF_TEST_TYPE, | |
92 | (char *)st->type, 0); | |
93 | st->params[n++] = | |
94 | OSSL_PARAM_construct_utf8_string(OSSL_PROV_PARAM_SELF_TEST_DESC, | |
95 | (char *)st->desc, 0); | |
96 | } | |
97 | st->params[n++] = OSSL_PARAM_construct_end(); | |
98 | } | |
99 | ||
100 | OSSL_SELF_TEST *OSSL_SELF_TEST_new(OSSL_CALLBACK *cb, void *cbarg) | |
101 | { | |
102 | OSSL_SELF_TEST *ret = OPENSSL_zalloc(sizeof(*ret)); | |
103 | ||
104 | if (ret == NULL) | |
105 | return NULL; | |
106 | ||
107 | ret->cb = cb; | |
108 | ret->cb_arg = cbarg; | |
109 | ret->phase = ""; | |
110 | ret->type = ""; | |
111 | ret->desc = ""; | |
112 | self_test_setparams(ret); | |
113 | return ret; | |
114 | } | |
115 | ||
116 | void OSSL_SELF_TEST_free(OSSL_SELF_TEST *st) | |
117 | { | |
118 | OPENSSL_free(st); | |
119 | } | |
120 | ||
121 | /* Can be used during application testing to log that a test has started. */ | |
122 | void OSSL_SELF_TEST_onbegin(OSSL_SELF_TEST *st, const char *type, | |
123 | const char *desc) | |
124 | { | |
125 | if (st != NULL && st->cb != NULL) { | |
126 | st->phase = OSSL_SELF_TEST_PHASE_START; | |
127 | st->type = type; | |
128 | st->desc = desc; | |
129 | self_test_setparams(st); | |
130 | (void)st->cb(st->params, st->cb_arg); | |
131 | } | |
132 | } | |
133 | ||
134 | /* | |
135 | * Can be used during application testing to log that a test has either | |
136 | * passed or failed. | |
137 | */ | |
138 | void OSSL_SELF_TEST_onend(OSSL_SELF_TEST *st, int ret) | |
139 | { | |
140 | if (st != NULL && st->cb != NULL) { | |
141 | st->phase = | |
142 | (ret == 1 ? OSSL_SELF_TEST_PHASE_PASS : OSSL_SELF_TEST_PHASE_FAIL); | |
143 | self_test_setparams(st); | |
144 | (void)st->cb(st->params, st->cb_arg); | |
145 | ||
146 | st->phase = OSSL_SELF_TEST_PHASE_NONE; | |
147 | st->type = OSSL_SELF_TEST_TYPE_NONE; | |
148 | st->desc = OSSL_SELF_TEST_DESC_NONE; | |
149 | } | |
150 | } | |
151 | ||
152 | /* | |
153 | * Used for failure testing. | |
154 | * | |
155 | * Call the applications SELF_TEST_cb() if it exists. | |
156 | * If the application callback decides to return 0 then the first byte of 'bytes' | |
157 | * is modified (corrupted). This is used to modify output signatures or | |
158 | * ciphertext before they are verified or decrypted. | |
159 | */ | |
7f9e7440 | 160 | int OSSL_SELF_TEST_oncorrupt_byte(OSSL_SELF_TEST *st, unsigned char *bytes) |
47c239c6 SL |
161 | { |
162 | if (st != NULL && st->cb != NULL) { | |
163 | st->phase = OSSL_SELF_TEST_PHASE_CORRUPT; | |
164 | self_test_setparams(st); | |
7f9e7440 | 165 | if (!st->cb(st->params, st->cb_arg)) { |
47c239c6 | 166 | bytes[0] ^= 1; |
7f9e7440 SL |
167 | return 1; |
168 | } | |
47c239c6 | 169 | } |
7f9e7440 | 170 | return 0; |
47c239c6 | 171 | } |