secmemtest.c 6.3 KB

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