Line data Source code
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 1 : test_crypto_rng_engine(void *arg)
23 : {
24 1 : (void)arg;
25 1 : RAND_METHOD dummy_method;
26 1 : memset(&dummy_method, 0, sizeof(dummy_method));
27 :
28 : /* We should be a no-op if we're already on RAND_OpenSSL */
29 1 : tt_int_op(0, OP_EQ, crypto_force_rand_ssleay());
30 1 : tt_assert(RAND_get_rand_method() == RAND_OpenSSL());
31 :
32 : /* We should correct the method if it's a dummy. */
33 1 : 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 1 : tt_assert(RAND_get_rand_method() == &dummy_method);
40 1 : tt_int_op(1, OP_EQ, crypto_force_rand_ssleay());
41 : #endif /* defined(LIBRESSL_VERSION_NUMBER) */
42 1 : tt_assert(RAND_get_rand_method() == RAND_OpenSSL());
43 :
44 : /* Make sure we aren't calling dummy_method */
45 1 : crypto_rand((void *) &dummy_method, sizeof(dummy_method));
46 1 : crypto_rand((void *) &dummy_method, sizeof(dummy_method));
47 :
48 1 : done:
49 1 : ;
50 1 : }
51 :
52 : #ifndef OPENSSL_1_1_API
53 : #define EVP_ENCODE_CTX_new() tor_malloc_zero(sizeof(EVP_ENCODE_CTX))
54 : #define EVP_ENCODE_CTX_free(ctx) tor_free(ctx)
55 : #endif
56 :
57 : /** Encode src into dest with OpenSSL's EVP Encode interface, returning the
58 : * length of the encoded data in bytes.
59 : */
60 : static int
61 256 : base64_encode_evp(char *dest, char *src, size_t srclen)
62 : {
63 256 : const unsigned char *s = (unsigned char*)src;
64 256 : EVP_ENCODE_CTX *ctx = EVP_ENCODE_CTX_new();
65 256 : int len, ret;
66 :
67 256 : EVP_EncodeInit(ctx);
68 256 : EVP_EncodeUpdate(ctx, (unsigned char *)dest, &len, s, (int)srclen);
69 256 : EVP_EncodeFinal(ctx, (unsigned char *)(dest + len), &ret);
70 256 : EVP_ENCODE_CTX_free(ctx);
71 256 : return ret+ len;
72 : }
73 :
74 : static void
75 1 : test_crypto_base64_encode_matches(void *arg)
76 : {
77 1 : (void)arg;
78 1 : int i, j;
79 1 : char data1[1024];
80 1 : char data2[1024];
81 1 : char data3[1024];
82 :
83 257 : for (i = 0; i < 256; i++) {
84 : /* Test the multiline format Base64 encoder with 0 .. 256 bytes of
85 : * output against OpenSSL.
86 : */
87 256 : const size_t enclen = base64_encode_size(i, BASE64_ENCODE_MULTILINE);
88 256 : data1[i] = i;
89 256 : j = base64_encode(data2, 1024, data1, i, BASE64_ENCODE_MULTILINE);
90 256 : tt_int_op(j, OP_EQ, enclen);
91 256 : j = base64_encode_evp(data3, data1, i);
92 256 : tt_int_op(j, OP_EQ, enclen);
93 256 : tt_mem_op(data2, OP_EQ, data3, enclen);
94 256 : tt_int_op(j, OP_EQ, strlen(data2));
95 : }
96 :
97 1 : done:
98 1 : ;
99 1 : }
100 :
101 : struct testcase_t crypto_openssl_tests[] = {
102 : { "rng_engine", test_crypto_rng_engine, TT_FORK, NULL, NULL },
103 : { "base64_encode_match", test_crypto_base64_encode_matches,
104 : TT_FORK, NULL, NULL },
105 : END_OF_TESTCASES
106 : };
|