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 } 166