| 
									
										
										
										
											2020-01-15 08:48:01 +08:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2020-03-03 12:02:36 +08:00
										 |  |  |  * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. | 
					
						
							| 
									
										
										
										
											2020-01-15 08:48:01 +08:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Licensed under the Apache License 2.0 (the "License").  You may not use | 
					
						
							|  |  |  |  * this file except in compliance with the License.  You can obtain a copy | 
					
						
							|  |  |  |  * in the file LICENSE in the source distribution or at | 
					
						
							|  |  |  |  * https://www.openssl.org/source/license.html
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <openssl/self_test.h>
 | 
					
						
							| 
									
										
										
										
											2020-03-03 12:02:36 +08:00
										 |  |  | #include <openssl/core_names.h>
 | 
					
						
							|  |  |  | #include <openssl/params.h>
 | 
					
						
							| 
									
										
										
										
											2020-01-15 08:48:01 +08:00
										 |  |  | #include "internal/cryptlib.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct self_test_cb_st | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     OSSL_CALLBACK *cb; | 
					
						
							|  |  |  |     void *cbarg; | 
					
						
							|  |  |  | } SELF_TEST_CB; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-03 12:02:36 +08:00
										 |  |  | struct ossl_self_test_st | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     /* local state variables */ | 
					
						
							|  |  |  |     const char *phase; | 
					
						
							|  |  |  |     const char *type; | 
					
						
							|  |  |  |     const char *desc; | 
					
						
							|  |  |  |     OSSL_CALLBACK *cb; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* callback related variables used to pass the state back to the user */ | 
					
						
							|  |  |  |     OSSL_PARAM params[4]; | 
					
						
							|  |  |  |     void *cb_arg; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-15 12:32:40 +08:00
										 |  |  | #ifndef FIPS_MODULE
 | 
					
						
							| 
									
										
										
										
											2020-10-15 17:55:50 +08:00
										 |  |  | static void *self_test_set_callback_new(OSSL_LIB_CTX *ctx) | 
					
						
							| 
									
										
										
										
											2020-01-15 08:48:01 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     SELF_TEST_CB *stcb; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     stcb = OPENSSL_zalloc(sizeof(*stcb)); | 
					
						
							|  |  |  |     return stcb; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void self_test_set_callback_free(void *stcb) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     OPENSSL_free(stcb); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-15 17:55:50 +08:00
										 |  |  | static const OSSL_LIB_CTX_METHOD self_test_set_callback_method = { | 
					
						
							| 
									
										
										
										
											2020-01-15 08:48:01 +08:00
										 |  |  |     self_test_set_callback_new, | 
					
						
							|  |  |  |     self_test_set_callback_free, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-15 17:55:50 +08:00
										 |  |  | static SELF_TEST_CB *get_self_test_callback(OSSL_LIB_CTX *libctx) | 
					
						
							| 
									
										
										
										
											2020-01-15 08:48:01 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-10-15 17:55:50 +08:00
										 |  |  |     return ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_SELF_TEST_CB_INDEX, | 
					
						
							|  |  |  |                                  &self_test_set_callback_method); | 
					
						
							| 
									
										
										
										
											2020-01-15 08:48:01 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-15 17:55:50 +08:00
										 |  |  | void OSSL_SELF_TEST_set_callback(OSSL_LIB_CTX *libctx, OSSL_CALLBACK *cb, | 
					
						
							| 
									
										
										
										
											2020-01-15 08:48:01 +08:00
										 |  |  |                                  void *cbarg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     SELF_TEST_CB *stcb = get_self_test_callback(libctx); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (stcb != NULL) { | 
					
						
							|  |  |  |         stcb->cb = cb; | 
					
						
							|  |  |  |         stcb->cbarg = cbarg; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-03-03 12:02:36 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-15 17:55:50 +08:00
										 |  |  | void OSSL_SELF_TEST_get_callback(OSSL_LIB_CTX *libctx, OSSL_CALLBACK **cb, | 
					
						
							| 
									
										
										
										
											2020-01-15 08:48:01 +08:00
										 |  |  |                                  void **cbarg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     SELF_TEST_CB *stcb = get_self_test_callback(libctx); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (cb != NULL) | 
					
						
							|  |  |  |         *cb = (stcb != NULL ? stcb->cb : NULL); | 
					
						
							|  |  |  |     if (cbarg != NULL) | 
					
						
							|  |  |  |         *cbarg = (stcb != NULL ? stcb->cbarg : NULL); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-09-15 12:32:40 +08:00
										 |  |  | #endif /* FIPS_MODULE */
 | 
					
						
							| 
									
										
										
										
											2020-03-03 12:02:36 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | static void self_test_setparams(OSSL_SELF_TEST *st) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     size_t n = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (st->cb != NULL) { | 
					
						
							|  |  |  |         st->params[n++] = | 
					
						
							|  |  |  |             OSSL_PARAM_construct_utf8_string(OSSL_PROV_PARAM_SELF_TEST_PHASE, | 
					
						
							|  |  |  |                                              (char *)st->phase, 0); | 
					
						
							|  |  |  |         st->params[n++] = | 
					
						
							|  |  |  |             OSSL_PARAM_construct_utf8_string(OSSL_PROV_PARAM_SELF_TEST_TYPE, | 
					
						
							|  |  |  |                                              (char *)st->type, 0); | 
					
						
							|  |  |  |         st->params[n++] = | 
					
						
							|  |  |  |             OSSL_PARAM_construct_utf8_string(OSSL_PROV_PARAM_SELF_TEST_DESC, | 
					
						
							|  |  |  |                                              (char *)st->desc, 0); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     st->params[n++] = OSSL_PARAM_construct_end(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | OSSL_SELF_TEST *OSSL_SELF_TEST_new(OSSL_CALLBACK *cb, void *cbarg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     OSSL_SELF_TEST *ret = OPENSSL_zalloc(sizeof(*ret)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (ret == NULL) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ret->cb = cb; | 
					
						
							|  |  |  |     ret->cb_arg = cbarg; | 
					
						
							|  |  |  |     ret->phase = ""; | 
					
						
							|  |  |  |     ret->type = ""; | 
					
						
							|  |  |  |     ret->desc = ""; | 
					
						
							|  |  |  |     self_test_setparams(ret); | 
					
						
							|  |  |  |     return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OSSL_SELF_TEST_free(OSSL_SELF_TEST *st) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     OPENSSL_free(st); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Can be used during application testing to log that a test has started. */ | 
					
						
							|  |  |  | void OSSL_SELF_TEST_onbegin(OSSL_SELF_TEST *st, const char *type, | 
					
						
							|  |  |  |                             const char *desc) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (st != NULL && st->cb != NULL) { | 
					
						
							|  |  |  |         st->phase = OSSL_SELF_TEST_PHASE_START; | 
					
						
							|  |  |  |         st->type = type; | 
					
						
							|  |  |  |         st->desc = desc; | 
					
						
							|  |  |  |         self_test_setparams(st); | 
					
						
							|  |  |  |         (void)st->cb(st->params, st->cb_arg); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Can be used during application testing to log that a test has either | 
					
						
							|  |  |  |  * passed or failed. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | void OSSL_SELF_TEST_onend(OSSL_SELF_TEST *st, int ret) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (st != NULL && st->cb != NULL) { | 
					
						
							|  |  |  |         st->phase = | 
					
						
							|  |  |  |             (ret == 1 ? OSSL_SELF_TEST_PHASE_PASS : OSSL_SELF_TEST_PHASE_FAIL); | 
					
						
							|  |  |  |         self_test_setparams(st); | 
					
						
							|  |  |  |         (void)st->cb(st->params, st->cb_arg); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         st->phase = OSSL_SELF_TEST_PHASE_NONE; | 
					
						
							|  |  |  |         st->type = OSSL_SELF_TEST_TYPE_NONE; | 
					
						
							|  |  |  |         st->desc = OSSL_SELF_TEST_DESC_NONE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Used for failure testing. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Call the applications SELF_TEST_cb() if it exists. | 
					
						
							|  |  |  |  * If the application callback decides to return 0 then the first byte of 'bytes' | 
					
						
							|  |  |  |  * is modified (corrupted). This is used to modify output signatures or | 
					
						
							|  |  |  |  * ciphertext before they are verified or decrypted. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2020-09-02 07:08:09 +08:00
										 |  |  | int OSSL_SELF_TEST_oncorrupt_byte(OSSL_SELF_TEST *st, unsigned char *bytes) | 
					
						
							| 
									
										
										
										
											2020-03-03 12:02:36 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     if (st != NULL && st->cb != NULL) { | 
					
						
							|  |  |  |         st->phase = OSSL_SELF_TEST_PHASE_CORRUPT; | 
					
						
							|  |  |  |         self_test_setparams(st); | 
					
						
							| 
									
										
										
										
											2020-09-02 07:08:09 +08:00
										 |  |  |         if (!st->cb(st->params, st->cb_arg)) { | 
					
						
							| 
									
										
										
										
											2020-03-03 12:02:36 +08:00
										 |  |  |             bytes[0] ^= 1; | 
					
						
							| 
									
										
										
										
											2020-09-02 07:08:09 +08:00
										 |  |  |             return 1; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-03-03 12:02:36 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-09-02 07:08:09 +08:00
										 |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2020-03-03 12:02:36 +08:00
										 |  |  | } |