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