test_crypto_openssl.c (2921B)
1 /* Copyright (c) 2001-2004, Roger Dingledine. 2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. 3 * Copyright (c) 2007-2021, The Tor Project, Inc. */ 4 /* See LICENSE for licensing information */ 5 6 #include "orconfig.h" 7 8 #define CRYPTO_RAND_PRIVATE 9 10 #include "lib/crypt_ops/compat_openssl.h" 11 #include "lib/crypt_ops/crypto_rand.h" 12 #include "lib/encoding/binascii.h" 13 #include "lib/malloc/malloc.h" 14 #include "test/test.h" 15 16 #include <openssl/evp.h> 17 #include <openssl/rand.h> 18 #include <string.h> 19 20 /* Test for rectifying openssl RAND engine. */ 21 static void 22 test_crypto_rng_engine(void *arg) 23 { 24 (void)arg; 25 RAND_METHOD dummy_method; 26 memset(&dummy_method, 0, sizeof(dummy_method)); 27 28 /* We should be a no-op if we're already on RAND_OpenSSL */ 29 tt_int_op(0, OP_EQ, crypto_force_rand_ssleay()); 30 tt_assert(RAND_get_rand_method() == RAND_OpenSSL()); 31 32 /* We should correct the method if it's a dummy. */ 33 RAND_set_rand_method(&dummy_method); 34 #ifdef LIBRESSL_VERSION_NUMBER 35 /* On libressl, you can't override the RNG. */ 36 tt_assert(RAND_get_rand_method() == RAND_OpenSSL()); 37 tt_int_op(0, OP_EQ, crypto_force_rand_ssleay()); 38 #else 39 tt_assert(RAND_get_rand_method() == &dummy_method); 40 tt_int_op(1, OP_EQ, crypto_force_rand_ssleay()); 41 #endif /* defined(LIBRESSL_VERSION_NUMBER) */ 42 tt_assert(RAND_get_rand_method() == RAND_OpenSSL()); 43 44 /* Make sure we aren't calling dummy_method */ 45 crypto_rand((void *) &dummy_method, sizeof(dummy_method)); 46 crypto_rand((void *) &dummy_method, sizeof(dummy_method)); 47 48 done: 49 ; 50 } 51 52 /** Encode src into dest with OpenSSL's EVP Encode interface, returning the 53 * length of the encoded data in bytes. 54 */ 55 static int 56 base64_encode_evp(char *dest, char *src, size_t srclen) 57 { 58 const unsigned char *s = (unsigned char*)src; 59 EVP_ENCODE_CTX *ctx = EVP_ENCODE_CTX_new(); 60 int len, ret; 61 62 EVP_EncodeInit(ctx); 63 EVP_EncodeUpdate(ctx, (unsigned char *)dest, &len, s, (int)srclen); 64 EVP_EncodeFinal(ctx, (unsigned char *)(dest + len), &ret); 65 EVP_ENCODE_CTX_free(ctx); 66 return ret+ len; 67 } 68 69 static void 70 test_crypto_base64_encode_matches(void *arg) 71 { 72 (void)arg; 73 int i, j; 74 char data1[1024]; 75 char data2[1024]; 76 char data3[1024]; 77 78 for (i = 0; i < 256; i++) { 79 /* Test the multiline format Base64 encoder with 0 .. 256 bytes of 80 * output against OpenSSL. 81 */ 82 const size_t enclen = base64_encode_size(i, BASE64_ENCODE_MULTILINE); 83 data1[i] = i; 84 j = base64_encode(data2, 1024, data1, i, BASE64_ENCODE_MULTILINE); 85 tt_int_op(j, OP_EQ, enclen); 86 j = base64_encode_evp(data3, data1, i); 87 tt_int_op(j, OP_EQ, enclen); 88 tt_mem_op(data2, OP_EQ, data3, enclen); 89 tt_int_op(j, OP_EQ, strlen(data2)); 90 } 91 92 done: 93 ; 94 } 95 96 struct testcase_t crypto_openssl_tests[] = { 97 { "rng_engine", test_crypto_rng_engine, TT_FORK, NULL, NULL }, 98 { "base64_encode_match", test_crypto_base64_encode_matches, 99 TT_FORK, NULL, NULL }, 100 END_OF_TESTCASES 101 };