fix: BN_swap mishandles flags (1.1.0)
[openssl.git] / test / secmemtest.c
1 /*
2  * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (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 <stdio.h>
11 #include <openssl/crypto.h>
12
13 #define perror_line()    perror_line1(__LINE__)
14 #define perror_line1(l)  perror_line2(l)
15 #define perror_line2(l)  perror("failed " #l)
16
17 int main(int argc, char **argv)
18 {
19 #if defined(OPENSSL_SYS_LINUX) || defined(OPENSSL_SYS_UNIX)
20     char *p = NULL, *q = NULL, *r = NULL, *s = NULL;
21
22     s = OPENSSL_secure_malloc(20);
23     /* s = non-secure 20 */
24     if (s == NULL) {
25         perror_line();
26         return 1;
27     }
28     if (CRYPTO_secure_allocated(s)) {
29         perror_line();
30         return 1;
31     }
32     r = OPENSSL_secure_malloc(20);
33     /* r = non-secure 20, s = non-secure 20 */
34     if (r == NULL) {
35         perror_line();
36         return 1;
37     }
38     if (!CRYPTO_secure_malloc_init(4096, 32)) {
39         perror_line();
40         return 1;
41     }
42     if (CRYPTO_secure_allocated(r)) {
43         perror_line();
44         return 1;
45     }
46     p = OPENSSL_secure_malloc(20);
47     /* r = non-secure 20, p = secure 20, s = non-secure 20 */
48     if (!CRYPTO_secure_allocated(p)) {
49         perror_line();
50         return 1;
51     }
52     /* 20 secure -> 32-byte minimum allocaton unit */
53     if (CRYPTO_secure_used() != 32) {
54         perror_line();
55         return 1;
56     }
57     q = OPENSSL_malloc(20);
58     /* r = non-secure 20, p = secure 20, q = non-secure 20, s = non-secure 20 */
59     if (CRYPTO_secure_allocated(q)) {
60         perror_line();
61         return 1;
62     }
63     OPENSSL_secure_clear_free(s, 20);
64     s = OPENSSL_secure_malloc(20);
65     /* r = non-secure 20, p = secure 20, q = non-secure 20, s = secure 20 */
66     if (!CRYPTO_secure_allocated(s)) {
67         perror_line();
68         return 1;
69     }
70     /* 2 * 20 secure -> 64 bytes allocated */
71     if (CRYPTO_secure_used() != 64) {
72         perror_line();
73         return 1;
74     }
75     OPENSSL_secure_clear_free(p, 20);
76     /* 20 secure -> 32 bytes allocated */
77     if (CRYPTO_secure_used() != 32) {
78         perror_line();
79         return 1;
80     }
81     OPENSSL_free(q);
82     /* should not complete, as secure memory is still allocated */
83     if (CRYPTO_secure_malloc_done()) {
84         perror_line();
85         return 1;
86     }
87     if (!CRYPTO_secure_malloc_initialized()) {
88         perror_line();
89         return 1;
90     }
91     OPENSSL_secure_free(s);
92     /* secure memory should now be 0, so done should complete */
93     if (CRYPTO_secure_used() != 0) {
94         perror_line();
95         return 1;
96     }
97     if (!CRYPTO_secure_malloc_done()) {
98         perror_line();
99         return 1;
100     }
101     if (CRYPTO_secure_malloc_initialized()) {
102         perror_line();
103         return 1;
104     }
105
106     fprintf(stderr, "Possible infinite loop: allocate more than available\n");
107     if (!CRYPTO_secure_malloc_init(32768, 16)) {
108         perror_line();
109         return 1;
110     }
111     if (OPENSSL_secure_malloc((size_t)-1) != NULL) {
112         perror_line();
113         return 1;
114     }
115     if (!CRYPTO_secure_malloc_done()) {
116         perror_line();
117         return 1;
118     }
119
120     /*
121      * If init fails, then initialized should be false, if not, this
122      * could cause an infinite loop secure_malloc, but we don't test it
123      */
124     if (!CRYPTO_secure_malloc_init(16, 16) &&
125         CRYPTO_secure_malloc_initialized()) {
126         CRYPTO_secure_malloc_done();
127         perror_line();
128         return 1;
129     }
130
131     /*-
132      * There was also a possible infinite loop when the number of
133      * elements was 1<<31, as |int i| was set to that, which is a
134      * negative number. However, it requires minimum input values:
135      *
136      * CRYPTO_secure_malloc_init((size_t)1<<34, (size_t)1<<4);
137      *
138      * Which really only works on 64-bit systems, since it took 16 GB
139      * secure memory arena to trigger the problem. It naturally takes
140      * corresponding amount of available virtual and physical memory
141      * for test to be feasible/representative. Since we can't assume
142      * that every system is equipped with that much memory, the test
143      * remains disabled. If the reader of this comment really wants
144      * to make sure that infinite loop is fixed, they can enable the
145      * code below.
146      */
147 # if 0
148     /*-
149      * On Linux and BSD this test has a chance to complete in minimal
150      * time and with minimum side effects, because mlock is likely to
151      * fail because of RLIMIT_MEMLOCK, which is customarily [much]
152      * smaller than 16GB. In other words Linux and BSD users can be
153      * limited by virtual space alone...
154      */
155     if (sizeof(size_t) > 4) {
156         fprintf(stderr, "Possible infinite loop: 1<<31 limit\n");
157         if (CRYPTO_secure_malloc_init((size_t)1<<34, (size_t)1<<4) == 0) {
158             perror_line();
159         } else if (!CRYPTO_secure_malloc_done()) {
160             perror_line();
161             return 1;
162         }
163     }
164 # endif
165
166     /* this can complete - it was not really secure */
167     OPENSSL_secure_free(r);
168 #else
169     /* Should fail. */
170     if (CRYPTO_secure_malloc_init(4096, 32)) {
171         perror_line();
172         return 1;
173     }
174 #endif
175     return 0;
176 }