1 /*
2  * Copyright 2025 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 /*
11  * This file provides implementation of various array allocation routines that
12  * perform integer overflow checking for size calculation.
13  */
14 
15 #include "internal/mem_alloc_utils.h"
16 #include <openssl/crypto.h>
17 
CRYPTO_malloc_array(size_t num,size_t size,const char * file,int line)18 void *CRYPTO_malloc_array(size_t num, size_t size, const char *file, int line)
19 {
20     size_t bytes;
21 
22     if (ossl_unlikely(!ossl_size_mul(num, size, &bytes, file, line)))
23         return NULL;
24 
25     return CRYPTO_malloc(bytes, file, line);
26 }
27 
CRYPTO_calloc(size_t num,size_t size,const char * file,int line)28 void *CRYPTO_calloc(size_t num, size_t size, const char *file, int line)
29 {
30     size_t bytes;
31 
32     if (ossl_unlikely(!ossl_size_mul(num, size, &bytes, file, line)))
33         return NULL;
34 
35     return CRYPTO_zalloc(bytes, file, line);
36 }
37 
CRYPTO_aligned_alloc_array(size_t num,size_t size,size_t align,void ** freeptr,const char * file,int line)38 void *CRYPTO_aligned_alloc_array(size_t num, size_t size, size_t align,
39                                  void **freeptr, const char *file, int line)
40 {
41     size_t bytes;
42 
43     if (ossl_unlikely(!ossl_size_mul(num, size, &bytes, file, line))) {
44         *freeptr = NULL;
45 
46         return NULL;
47     }
48 
49     return CRYPTO_aligned_alloc(bytes, align, freeptr, file, line);
50 }
51 
CRYPTO_realloc_array(void * addr,size_t num,size_t size,const char * file,int line)52 void *CRYPTO_realloc_array(void *addr, size_t num, size_t size,
53                            const char *file, int line)
54 {
55     size_t bytes;
56 
57     if (ossl_unlikely(!ossl_size_mul(num, size, &bytes, file, line)))
58         return NULL;
59 
60     return CRYPTO_realloc(addr, bytes, file, line);
61 }
62 
CRYPTO_clear_realloc_array(void * addr,size_t old_num,size_t num,size_t size,const char * file,int line)63 void *CRYPTO_clear_realloc_array(void *addr, size_t old_num, size_t num,
64                                  size_t size, const char *file, int line)
65 {
66     size_t old_bytes, bytes = 0;
67 
68     if (ossl_unlikely(!ossl_size_mul(old_num, size, &old_bytes, file, line)
69                       || !ossl_size_mul(num, size, &bytes, file, line)))
70         return NULL;
71 
72     return CRYPTO_clear_realloc(addr, old_bytes, bytes, file, line);
73 }
74 
CRYPTO_secure_malloc_array(size_t num,size_t size,const char * file,int line)75 void *CRYPTO_secure_malloc_array(size_t num, size_t size,
76                                  const char *file, int line)
77 {
78     size_t bytes;
79 
80     if (ossl_unlikely(!ossl_size_mul(num, size, &bytes, file, line)))
81         return NULL;
82 
83     return CRYPTO_secure_malloc(bytes, file, line);
84 }
85 
CRYPTO_secure_calloc(size_t num,size_t size,const char * file,int line)86 void *CRYPTO_secure_calloc(size_t num, size_t size, const char *file, int line)
87 {
88     size_t bytes;
89 
90     if (ossl_unlikely(!ossl_size_mul(num, size, &bytes, file, line)))
91         return NULL;
92 
93     return CRYPTO_secure_zalloc(bytes, file, line);
94 }
95