1/*
2 * Copyright (c) 1999-2001,2005-2007,2010-2012,2014 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24/*
25 * sslMemory.c - Memory allocator implementation
26 */
27
28/* THIS FILE CONTAINS KERNEL CODE */
29
30#include "sslMemory.h"
31#include "sslDebug.h"
32
33#include <string.h>			/* memset */
34#include <AssertMacros.h>
35
36// MARK: -
37// MARK: Basic low-level malloc/free
38
39/*
40 * For now, all allocs/frees go thru here.
41 */
42
43#ifdef KERNEL
44
45/* BSD Malloc */
46#include <sys/malloc.h>
47#include <IOKit/IOLib.h>
48#include <libkern/libkern.h>
49
50/* Define this for debugging sslMalloc and sslFree */
51//#define SSL_CANARIS
52
53void *
54sslMalloc(size_t length)
55{
56    void *p;
57
58#ifdef SSL_CANARIS
59    length+=8;
60#endif
61
62    p = _MALLOC(length, M_TEMP, M_WAITOK);
63    check(p);
64
65    if(p==NULL)
66        return p;
67
68#ifdef SSL_CANARIS
69    *(uint32_t *)p=(uint32_t)length-8;
70    printf("sslMalloc @%p of 0x%08lx bytes\n", p, length-8);
71    *(uint32_t *)(p+length-4)=0xdeadbeed;
72    p+=4;
73#endif
74
75    return p;
76}
77
78void
79sslFree(void *p)
80{
81	if(p != NULL) {
82
83#ifdef SSL_CANARIS
84        p=p-4;
85        uint32_t len=*(uint32_t *)p;
86        uint32_t marker=*(uint32_t *)(p+4+len);
87        printf("sslFree @%p len=0x%08x\n", p, len);
88        if(marker!=0xdeadbeef)
89            panic("Buffer overflow in SSL!\n");
90#endif
91
92        _FREE(p, M_TEMP);
93	}
94}
95
96void *
97sslRealloc(void *oldPtr, size_t oldLen, size_t newLen)
98{
99    /* _REALLOC is in sys/malloc.h but is only exported in debug kernel */
100    /* return _REALLOC(oldPtr, newLen, M_TEMP, M_NOWAIT); */
101
102    /* FIXME */
103    void *newPtr;
104    if(newLen>oldLen) {
105        newPtr=sslMalloc(newLen);
106        if(newPtr) {
107            memcpy(newPtr, oldPtr, oldLen);
108            sslFree(oldPtr);
109        }
110    } else {
111        newPtr=oldPtr;
112    }
113    return newPtr;
114}
115
116#else
117
118#include <stdlib.h>
119
120void *
121sslMalloc(size_t length)
122{
123	return malloc(length);
124}
125
126void
127sslFree(void *p)
128{
129	if(p != NULL) {
130		free(p);
131	}
132}
133
134void *
135sslRealloc(void *oldPtr, size_t oldLen, size_t newLen)
136{
137	return realloc(oldPtr, newLen);
138}
139
140#endif
141
142// MARK: -
143// MARK: SSLBuffer-level alloc/free
144
145int SSLAllocBuffer(
146	SSLBuffer *buf,
147	size_t length)
148{
149	buf->data = (uint8_t *)sslMalloc(length);
150	if(buf->data == NULL) {
151        sslErrorLog("SSLAllocBuffer: NULL buf!\n");
152        check(0);
153		buf->length = 0;
154		return -1;
155	}
156    buf->length = length;
157    return 0;
158}
159
160int
161SSLFreeBuffer(SSLBuffer *buf)
162{
163	if(buf == NULL) {
164		sslErrorLog("SSLFreeBuffer: NULL buf!\n");
165        check(0);
166		return -1;
167	}
168    sslFree(buf->data);
169    buf->data = NULL;
170    buf->length = 0;
171    return 0;
172}
173
174int
175SSLReallocBuffer(SSLBuffer *buf, size_t newSize)
176{
177	buf->data = (uint8_t *)sslRealloc(buf->data, buf->length, newSize);
178	if(buf->data == NULL) {
179        sslErrorLog("SSLReallocBuffer: NULL buf!\n");
180        check(0);
181		buf->length = 0;
182		return -1;
183	}
184	buf->length = newSize;
185	return 0;
186}
187
188// MARK: -
189// MARK: Convenience routines
190
191uint8_t *sslAllocCopy(
192	const uint8_t *src,
193	size_t len)
194{
195	uint8_t *dst;
196
197	dst = (uint8_t *)sslMalloc(len);
198	if(dst == NULL) {
199		return NULL;
200	}
201	memmove(dst, src, len);
202	return dst;
203}
204
205int SSLAllocCopyBuffer(
206	const SSLBuffer *src,
207	SSLBuffer **dst)		// buffer and data mallocd and returned
208{
209	int serr;
210
211	SSLBuffer *rtn = (SSLBuffer *)sslMalloc(sizeof(SSLBuffer));
212	if(rtn == NULL) {
213        sslErrorLog("SSLAllocCopyBuffer: NULL buf!\n");
214        check(0);
215		return -1;
216	}
217	serr = SSLCopyBuffer(src, rtn);
218	if(serr) {
219		sslFree(rtn);
220	}
221	else {
222		*dst = rtn;
223	}
224	return serr;
225}
226
227int SSLCopyBufferFromData(
228	const void *src,
229	size_t len,
230	SSLBuffer *dst)		// data mallocd and returned
231{
232	dst->data = sslAllocCopy((const uint8_t *)src, len);
233	if(dst->data == NULL) {
234        sslErrorLog("SSLCopyBufferFromData: NULL buf!\n");
235        check(0);
236		return -1;
237	}
238    dst->length = len;
239    return 0;
240}
241
242int SSLCopyBuffer(
243	const SSLBuffer *src,
244	SSLBuffer *dst)		// data mallocd and returned
245{
246	return SSLCopyBufferFromData(src->data, src->length, dst);
247}
248
249