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