1 | /*
|
---|
2 | * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
|
---|
3 | *
|
---|
4 | * Licensed under the Apache License 2.0 (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 "internal/cryptlib.h"
|
---|
12 | #include <openssl/buffer.h>
|
---|
13 |
|
---|
14 | /*
|
---|
15 | * LIMIT_BEFORE_EXPANSION is the maximum n such that (n+3)/3*4 < 2**31. That
|
---|
16 | * function is applied in several functions in this file and this limit
|
---|
17 | * ensures that the result fits in an int.
|
---|
18 | */
|
---|
19 | #define LIMIT_BEFORE_EXPANSION 0x5ffffffc
|
---|
20 |
|
---|
21 | BUF_MEM *BUF_MEM_new_ex(unsigned long flags)
|
---|
22 | {
|
---|
23 | BUF_MEM *ret;
|
---|
24 |
|
---|
25 | ret = BUF_MEM_new();
|
---|
26 | if (ret != NULL)
|
---|
27 | ret->flags = flags;
|
---|
28 | return ret;
|
---|
29 | }
|
---|
30 |
|
---|
31 | BUF_MEM *BUF_MEM_new(void)
|
---|
32 | {
|
---|
33 | BUF_MEM *ret;
|
---|
34 |
|
---|
35 | ret = OPENSSL_zalloc(sizeof(*ret));
|
---|
36 | if (ret == NULL) {
|
---|
37 | ERR_raise(ERR_LIB_BUF, ERR_R_MALLOC_FAILURE);
|
---|
38 | return NULL;
|
---|
39 | }
|
---|
40 | return ret;
|
---|
41 | }
|
---|
42 |
|
---|
43 | void BUF_MEM_free(BUF_MEM *a)
|
---|
44 | {
|
---|
45 | if (a == NULL)
|
---|
46 | return;
|
---|
47 | if (a->data != NULL) {
|
---|
48 | if (a->flags & BUF_MEM_FLAG_SECURE)
|
---|
49 | OPENSSL_secure_clear_free(a->data, a->max);
|
---|
50 | else
|
---|
51 | OPENSSL_clear_free(a->data, a->max);
|
---|
52 | }
|
---|
53 | OPENSSL_free(a);
|
---|
54 | }
|
---|
55 |
|
---|
56 | /* Allocate a block of secure memory; copy over old data if there
|
---|
57 | * was any, and then free it. */
|
---|
58 | static char *sec_alloc_realloc(BUF_MEM *str, size_t len)
|
---|
59 | {
|
---|
60 | char *ret;
|
---|
61 |
|
---|
62 | ret = OPENSSL_secure_malloc(len);
|
---|
63 | if (str->data != NULL) {
|
---|
64 | if (ret != NULL) {
|
---|
65 | memcpy(ret, str->data, str->length);
|
---|
66 | OPENSSL_secure_clear_free(str->data, str->length);
|
---|
67 | str->data = NULL;
|
---|
68 | }
|
---|
69 | }
|
---|
70 | return ret;
|
---|
71 | }
|
---|
72 |
|
---|
73 | size_t BUF_MEM_grow(BUF_MEM *str, size_t len)
|
---|
74 | {
|
---|
75 | char *ret;
|
---|
76 | size_t n;
|
---|
77 |
|
---|
78 | if (str->length >= len) {
|
---|
79 | str->length = len;
|
---|
80 | return len;
|
---|
81 | }
|
---|
82 | if (str->max >= len) {
|
---|
83 | if (str->data != NULL)
|
---|
84 | memset(&str->data[str->length], 0, len - str->length);
|
---|
85 | str->length = len;
|
---|
86 | return len;
|
---|
87 | }
|
---|
88 | /* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */
|
---|
89 | if (len > LIMIT_BEFORE_EXPANSION) {
|
---|
90 | ERR_raise(ERR_LIB_BUF, ERR_R_MALLOC_FAILURE);
|
---|
91 | return 0;
|
---|
92 | }
|
---|
93 | n = (len + 3) / 3 * 4;
|
---|
94 | if ((str->flags & BUF_MEM_FLAG_SECURE))
|
---|
95 | ret = sec_alloc_realloc(str, n);
|
---|
96 | else
|
---|
97 | ret = OPENSSL_realloc(str->data, n);
|
---|
98 | if (ret == NULL) {
|
---|
99 | ERR_raise(ERR_LIB_BUF, ERR_R_MALLOC_FAILURE);
|
---|
100 | len = 0;
|
---|
101 | } else {
|
---|
102 | str->data = ret;
|
---|
103 | str->max = n;
|
---|
104 | memset(&str->data[str->length], 0, len - str->length);
|
---|
105 | str->length = len;
|
---|
106 | }
|
---|
107 | return len;
|
---|
108 | }
|
---|
109 |
|
---|
110 | size_t BUF_MEM_grow_clean(BUF_MEM *str, size_t len)
|
---|
111 | {
|
---|
112 | char *ret;
|
---|
113 | size_t n;
|
---|
114 |
|
---|
115 | if (str->length >= len) {
|
---|
116 | if (str->data != NULL)
|
---|
117 | memset(&str->data[len], 0, str->length - len);
|
---|
118 | str->length = len;
|
---|
119 | return len;
|
---|
120 | }
|
---|
121 | if (str->max >= len) {
|
---|
122 | memset(&str->data[str->length], 0, len - str->length);
|
---|
123 | str->length = len;
|
---|
124 | return len;
|
---|
125 | }
|
---|
126 | /* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */
|
---|
127 | if (len > LIMIT_BEFORE_EXPANSION) {
|
---|
128 | ERR_raise(ERR_LIB_BUF, ERR_R_MALLOC_FAILURE);
|
---|
129 | return 0;
|
---|
130 | }
|
---|
131 | n = (len + 3) / 3 * 4;
|
---|
132 | if ((str->flags & BUF_MEM_FLAG_SECURE))
|
---|
133 | ret = sec_alloc_realloc(str, n);
|
---|
134 | else
|
---|
135 | ret = OPENSSL_clear_realloc(str->data, str->max, n);
|
---|
136 | if (ret == NULL) {
|
---|
137 | ERR_raise(ERR_LIB_BUF, ERR_R_MALLOC_FAILURE);
|
---|
138 | len = 0;
|
---|
139 | } else {
|
---|
140 | str->data = ret;
|
---|
141 | str->max = n;
|
---|
142 | memset(&str->data[str->length], 0, len - str->length);
|
---|
143 | str->length = len;
|
---|
144 | }
|
---|
145 | return len;
|
---|
146 | }
|
---|
147 |
|
---|
148 | void BUF_reverse(unsigned char *out, const unsigned char *in, size_t size)
|
---|
149 | {
|
---|
150 | size_t i;
|
---|
151 | if (in) {
|
---|
152 | out += size - 1;
|
---|
153 | for (i = 0; i < size; i++)
|
---|
154 | *out-- = *in++;
|
---|
155 | } else {
|
---|
156 | unsigned char *q;
|
---|
157 | char c;
|
---|
158 | q = out + size - 1;
|
---|
159 | for (i = 0; i < size / 2; i++) {
|
---|
160 | c = *q;
|
---|
161 | *q-- = *out;
|
---|
162 | *out++ = c;
|
---|
163 | }
|
---|
164 | }
|
---|
165 | }
|
---|