xref: /titanic_51/usr/src/common/crypto/ecc/secitem.c (revision ff17c8bf86c3e567734be83f90267edee20f580f)
1 /* ***** BEGIN LICENSE BLOCK *****
2  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3  *
4  * The contents of this file are subject to the Mozilla Public License Version
5  * 1.1 (the "License"); you may not use this file except in compliance with
6  * the License. You may obtain a copy of the License at
7  * http://www.mozilla.org/MPL/
8  *
9  * Software distributed under the License is distributed on an "AS IS" basis,
10  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11  * for the specific language governing rights and limitations under the
12  * License.
13  *
14  * The Original Code is the Netscape security libraries.
15  *
16  * The Initial Developer of the Original Code is
17  * Netscape Communications Corporation.
18  * Portions created by the Initial Developer are Copyright (C) 1994-2000
19  * the Initial Developer. All Rights Reserved.
20  *
21  * Contributor(s):
22  *
23  * Alternatively, the contents of this file may be used under the terms of
24  * either the GNU General Public License Version 2 or later (the "GPL"), or
25  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26  * in which case the provisions of the GPL or the LGPL are applicable instead
27  * of those above. If you wish to allow use of your version of this file only
28  * under the terms of either the GPL or the LGPL, and not to allow others to
29  * use your version of this file under the terms of the MPL, indicate your
30  * decision by deleting the provisions above and replace them with the notice
31  * and other provisions required by the GPL or the LGPL. If you do not delete
32  * the provisions above, a recipient may use your version of this file under
33  * the terms of any one of the MPL, the GPL or the LGPL.
34  *
35  * ***** END LICENSE BLOCK ***** */
36 /*
37  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
38  * Use is subject to license terms.
39  *
40  * Sun elects to use this software under the MPL license.
41  */
42 
43 #pragma ident	"%Z%%M%	%I%	%E% SMI"
44 
45 /*
46  * Support routines for SECItem data structure.
47  *
48  * $Id: secitem.c,v 1.14 2006/05/22 22:24:34 wtchang%redhat.com Exp $
49  */
50 
51 #include <sys/types.h>
52 #include <sys/systm.h>
53 #include <sys/param.h>
54 #ifdef _KERNEL
55 #include <sys/kmem.h>
56 #else
57 #include <string.h>
58 #include <strings.h>
59 #include <assert.h>
60 #endif
61 #include "ec.h"
62 #include "ecl-curve.h"
63 #include "ecc_impl.h"
64 
65 void SECITEM_FreeItem(SECItem *, PRBool);
66 
67 SECItem *
68 SECITEM_AllocItem(PRArenaPool *arena, SECItem *item, unsigned int len,
69     int kmflag)
70 {
71     SECItem *result = NULL;
72     void *mark = NULL;
73 
74     if (arena != NULL) {
75 	mark = PORT_ArenaMark(arena);
76     }
77 
78     if (item == NULL) {
79 	if (arena != NULL) {
80 	    result = PORT_ArenaZAlloc(arena, sizeof(SECItem), kmflag);
81 	} else {
82 	    result = PORT_ZAlloc(sizeof(SECItem), kmflag);
83 	}
84 	if (result == NULL) {
85 	    goto loser;
86 	}
87     } else {
88 	PORT_Assert(item->data == NULL);
89 	result = item;
90     }
91 
92     result->len = len;
93     if (len) {
94 	if (arena != NULL) {
95 	    result->data = PORT_ArenaAlloc(arena, len, kmflag);
96 	} else {
97 	    result->data = PORT_Alloc(len, kmflag);
98 	}
99 	if (result->data == NULL) {
100 	    goto loser;
101 	}
102     } else {
103 	result->data = NULL;
104     }
105 
106     if (mark) {
107 	PORT_ArenaUnmark(arena, mark);
108     }
109     return(result);
110 
111 loser:
112     if ( arena != NULL ) {
113 	if (mark) {
114 	    PORT_ArenaRelease(arena, mark);
115 	}
116 	if (item != NULL) {
117 	    item->data = NULL;
118 	    item->len = 0;
119 	}
120     } else {
121 	if (result != NULL) {
122 	    SECITEM_FreeItem(result, (item == NULL) ? PR_TRUE : PR_FALSE);
123 	}
124 	/*
125 	 * If item is not NULL, the above has set item->data and
126 	 * item->len to 0.
127 	 */
128     }
129     return(NULL);
130 }
131 
132 SECStatus
133 SECITEM_CopyItem(PRArenaPool *arena, SECItem *to, const SECItem *from,
134    int kmflag)
135 {
136     to->type = from->type;
137     if (from->data && from->len) {
138 	if ( arena ) {
139 	    to->data = (unsigned char*) PORT_ArenaAlloc(arena, from->len,
140 		kmflag);
141 	} else {
142 	    to->data = (unsigned char*) PORT_Alloc(from->len, kmflag);
143 	}
144 
145 	if (!to->data) {
146 	    return SECFailure;
147 	}
148 	PORT_Memcpy(to->data, from->data, from->len);
149 	to->len = from->len;
150     } else {
151 	to->data = 0;
152 	to->len = 0;
153     }
154     return SECSuccess;
155 }
156 
157 void
158 SECITEM_FreeItem(SECItem *zap, PRBool freeit)
159 {
160     if (zap) {
161 #ifdef _KERNEL
162 	kmem_free(zap->data, zap->len);
163 #else
164 	free(zap->data);
165 #endif
166 	zap->data = 0;
167 	zap->len = 0;
168 	if (freeit) {
169 #ifdef _KERNEL
170 	    kmem_free(zap, sizeof (SECItem));
171 #else
172 	    free(zap);
173 #endif
174 	}
175     }
176 }
177