1/*
2 * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
3 * Use is subject to license terms.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this library; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/* *********************************************************************
25 *
26 * The Original Code is the Netscape security libraries.
27 *
28 * The Initial Developer of the Original Code is
29 * Netscape Communications Corporation.
30 * Portions created by the Initial Developer are Copyright (C) 1994-2000
31 * the Initial Developer. All Rights Reserved.
32 *
33 * Contributor(s):
34 *
35 * Last Modified Date from the Original Code: March 2012
36 *********************************************************************** */
37
38/*
39 * Support routines for SECItem data structure.
40 *
41 * $Id: secitem.c,v 1.14 2006/05/22 22:24:34 wtchang%redhat.com Exp $
42 */
43
44#include <sys/types.h>
45
46#ifndef _WIN32
47#if !defined(__linux__) && !defined(_ALLBSD_SOURCE)
48#include <sys/systm.h>
49#endif /* __linux__ || _ALLBSD_SOURCE */
50#include <sys/param.h>
51#endif /* _WIN32 */
52
53#ifdef _KERNEL
54#include <sys/kmem.h>
55#else
56#include <string.h>
57
58#ifndef _WIN32
59#include <strings.h>
60#endif /* _WIN32 */
61
62#include <assert.h>
63#endif
64#include "ec.h"
65#include "ecl-curve.h"
66#include "ecc_impl.h"
67
68void SECITEM_FreeItem(SECItem *, PRBool);
69
70SECItem *
71SECITEM_AllocItem(PRArenaPool *arena, SECItem *item, unsigned int len,
72    int kmflag)
73{
74    SECItem *result = NULL;
75    void *mark = NULL;
76
77    if (arena != NULL) {
78        mark = PORT_ArenaMark(arena);
79    }
80
81    if (item == NULL) {
82        if (arena != NULL) {
83            result = PORT_ArenaZAlloc(arena, sizeof(SECItem), kmflag);
84        } else {
85            result = PORT_ZAlloc(sizeof(SECItem), kmflag);
86        }
87        if (result == NULL) {
88            goto loser;
89        }
90    } else {
91        PORT_Assert(item->data == NULL);
92        result = item;
93    }
94
95    result->len = len;
96    if (len) {
97        if (arena != NULL) {
98            result->data = PORT_ArenaAlloc(arena, len, kmflag);
99        } else {
100            result->data = PORT_Alloc(len, kmflag);
101        }
102        if (result->data == NULL) {
103            goto loser;
104        }
105    } else {
106        result->data = NULL;
107    }
108
109    if (mark) {
110        PORT_ArenaUnmark(arena, mark);
111    }
112    return(result);
113
114loser:
115    if ( arena != NULL ) {
116        if (mark) {
117            PORT_ArenaRelease(arena, mark);
118        }
119        if (item != NULL) {
120            item->data = NULL;
121            item->len = 0;
122        }
123    } else {
124        if (result != NULL) {
125            SECITEM_FreeItem(result, (item == NULL) ? PR_TRUE : PR_FALSE);
126        }
127        /*
128         * If item is not NULL, the above has set item->data and
129         * item->len to 0.
130         */
131    }
132    return(NULL);
133}
134
135SECStatus
136SECITEM_CopyItem(PRArenaPool *arena, SECItem *to, const SECItem *from,
137   int kmflag)
138{
139    to->type = from->type;
140    if (from->data && from->len) {
141        if ( arena ) {
142            to->data = (unsigned char*) PORT_ArenaAlloc(arena, from->len,
143                kmflag);
144        } else {
145            to->data = (unsigned char*) PORT_Alloc(from->len, kmflag);
146        }
147
148        if (!to->data) {
149            return SECFailure;
150        }
151        PORT_Memcpy(to->data, from->data, from->len);
152        to->len = from->len;
153    } else {
154        to->data = 0;
155        to->len = 0;
156    }
157    return SECSuccess;
158}
159
160void
161SECITEM_FreeItem(SECItem *zap, PRBool freeit)
162{
163    if (zap) {
164#ifdef _KERNEL
165        kmem_free(zap->data, zap->len);
166#else
167        free(zap->data);
168#endif
169        zap->data = 0;
170        zap->len = 0;
171        if (freeit) {
172#ifdef _KERNEL
173            kmem_free(zap, sizeof (SECItem));
174#else
175            free(zap);
176#endif
177        }
178    }
179}
180