OLD | NEW |
1 /* This Source Code Form is subject to the terms of the Mozilla Public | 1 /* This Source Code Form is subject to the terms of the Mozilla Public |
2 * License, v. 2.0. If a copy of the MPL was not distributed with this | 2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
4 | 4 |
5 #include "blapi.h" | 5 #include "blapi.h" |
6 #include "ec.h" | 6 #include "ec.h" |
7 #include "ecl-curve.h" | 7 #include "ecl-curve.h" |
8 #include "nss.h" | 8 #include "nss.h" |
9 #include "secutil.h" | 9 #include "secutil.h" |
10 #include "pkcs11.h" | 10 #include "pkcs11.h" |
11 #include <nspr.h> | 11 #include <nspr.h> |
12 #include <stdio.h> | 12 #include <stdio.h> |
13 #include <strings.h> | 13 #include <strings.h> |
14 #include <assert.h> | 14 #include <assert.h> |
15 | 15 |
16 #include <time.h> | 16 #include <time.h> |
17 #include <sys/time.h> | 17 #include <sys/time.h> |
18 #include <sys/resource.h> | 18 #include <sys/resource.h> |
19 | 19 |
20 #define __PASTE(x,y) x##y | 20 #define __PASTE(x, y) x##y |
21 | 21 |
22 /* | 22 /* |
23 * Get the NSS specific PKCS #11 function names. | 23 * Get the NSS specific PKCS #11 function names. |
24 */ | 24 */ |
25 #undef CK_PKCS11_FUNCTION_INFO | 25 #undef CK_PKCS11_FUNCTION_INFO |
26 #undef CK_NEED_ARG_LIST | 26 #undef CK_NEED_ARG_LIST |
27 | 27 |
28 #define CK_EXTERN extern | 28 #define CK_EXTERN extern |
29 #define CK_PKCS11_FUNCTION_INFO(func) \ | 29 #define CK_PKCS11_FUNCTION_INFO(func) CK_RV __PASTE(NS, func) |
30 » » CK_RV __PASTE(NS,func) | 30 #define CK_NEED_ARG_LIST 1 |
31 #define CK_NEED_ARG_LIST» 1 | |
32 | 31 |
33 #include "pkcs11f.h" | 32 #include "pkcs11f.h" |
34 | 33 |
35 | |
36 | |
37 /* mapping between ECCurveName enum and pointers to ECCurveParams */ | 34 /* mapping between ECCurveName enum and pointers to ECCurveParams */ |
38 static SECOidTag ecCurve_oid_map[] = { | 35 static SECOidTag ecCurve_oid_map[] = { |
39 SEC_OID_UNKNOWN,» /* ECCurve_noName */ | 36 SEC_OID_UNKNOWN, /* ECCurve_noName */ |
40 SEC_OID_ANSIX962_EC_PRIME192V1, /* ECCurve_NIST_P192 */ | 37 SEC_OID_ANSIX962_EC_PRIME192V1, /* ECCurve_NIST_P192 */ |
41 SEC_OID_SECG_EC_SECP224R1, /* ECCurve_NIST_P224 */ | 38 SEC_OID_SECG_EC_SECP224R1, /* ECCurve_NIST_P224 */ |
42 SEC_OID_ANSIX962_EC_PRIME256V1, /* ECCurve_NIST_P256 */ | 39 SEC_OID_ANSIX962_EC_PRIME256V1, /* ECCurve_NIST_P256 */ |
43 SEC_OID_SECG_EC_SECP384R1, /* ECCurve_NIST_P384 */ | 40 SEC_OID_SECG_EC_SECP384R1, /* ECCurve_NIST_P384 */ |
44 SEC_OID_SECG_EC_SECP521R1, /* ECCurve_NIST_P521 */ | 41 SEC_OID_SECG_EC_SECP521R1, /* ECCurve_NIST_P521 */ |
45 SEC_OID_SECG_EC_SECT163K1, /* ECCurve_NIST_K163 */ | 42 SEC_OID_SECG_EC_SECT163K1, /* ECCurve_NIST_K163 */ |
46 SEC_OID_SECG_EC_SECT163R1, /* ECCurve_NIST_B163 */ | 43 SEC_OID_SECG_EC_SECT163R1, /* ECCurve_NIST_B163 */ |
47 SEC_OID_SECG_EC_SECT233K1, /* ECCurve_NIST_K233 */ | 44 SEC_OID_SECG_EC_SECT233K1, /* ECCurve_NIST_K233 */ |
48 SEC_OID_SECG_EC_SECT233R1, /* ECCurve_NIST_B233 */ | 45 SEC_OID_SECG_EC_SECT233R1, /* ECCurve_NIST_B233 */ |
49 SEC_OID_SECG_EC_SECT283K1, /* ECCurve_NIST_K283 */ | 46 SEC_OID_SECG_EC_SECT283K1, /* ECCurve_NIST_K283 */ |
50 SEC_OID_SECG_EC_SECT283R1, /* ECCurve_NIST_B283 */ | 47 SEC_OID_SECG_EC_SECT283R1, /* ECCurve_NIST_B283 */ |
51 SEC_OID_SECG_EC_SECT409K1, /* ECCurve_NIST_K409 */ | 48 SEC_OID_SECG_EC_SECT409K1, /* ECCurve_NIST_K409 */ |
52 SEC_OID_SECG_EC_SECT409R1, /* ECCurve_NIST_B409 */ | 49 SEC_OID_SECG_EC_SECT409R1, /* ECCurve_NIST_B409 */ |
53 SEC_OID_SECG_EC_SECT571K1, /* ECCurve_NIST_K571 */ | 50 SEC_OID_SECG_EC_SECT571K1, /* ECCurve_NIST_K571 */ |
54 SEC_OID_SECG_EC_SECT571R1, /* ECCurve_NIST_B571 */ | 51 SEC_OID_SECG_EC_SECT571R1, /* ECCurve_NIST_B571 */ |
55 SEC_OID_ANSIX962_EC_PRIME192V2, ··· | 52 SEC_OID_ANSIX962_EC_PRIME192V2, SEC_OID_ANSIX962_EC_PRIME192V3, |
56 SEC_OID_ANSIX962_EC_PRIME192V3, | 53 SEC_OID_ANSIX962_EC_PRIME239V1, SEC_OID_ANSIX962_EC_PRIME239V2, |
57 SEC_OID_ANSIX962_EC_PRIME239V1, | 54 SEC_OID_ANSIX962_EC_PRIME239V3, SEC_OID_ANSIX962_EC_C2PNB163V1, |
58 SEC_OID_ANSIX962_EC_PRIME239V2, | 55 SEC_OID_ANSIX962_EC_C2PNB163V2, SEC_OID_ANSIX962_EC_C2PNB163V3, |
59 SEC_OID_ANSIX962_EC_PRIME239V3, | 56 SEC_OID_ANSIX962_EC_C2PNB176V1, SEC_OID_ANSIX962_EC_C2TNB191V1, |
60 » SEC_OID_ANSIX962_EC_C2PNB163V1, | 57 SEC_OID_ANSIX962_EC_C2TNB191V2, SEC_OID_ANSIX962_EC_C2TNB191V3, |
61 » SEC_OID_ANSIX962_EC_C2PNB163V2, | 58 SEC_OID_ANSIX962_EC_C2PNB208W1, SEC_OID_ANSIX962_EC_C2TNB239V1, |
62 » SEC_OID_ANSIX962_EC_C2PNB163V3, | 59 SEC_OID_ANSIX962_EC_C2TNB239V2, SEC_OID_ANSIX962_EC_C2TNB239V3, |
63 SEC_OID_ANSIX962_EC_C2PNB176V1, | 60 SEC_OID_ANSIX962_EC_C2PNB272W1, SEC_OID_ANSIX962_EC_C2PNB304W1, |
64 SEC_OID_ANSIX962_EC_C2TNB191V1, | 61 SEC_OID_ANSIX962_EC_C2TNB359V1, SEC_OID_ANSIX962_EC_C2PNB368W1, |
65 SEC_OID_ANSIX962_EC_C2TNB191V2, | 62 SEC_OID_ANSIX962_EC_C2TNB431R1, SEC_OID_SECG_EC_SECP112R1, |
66 SEC_OID_ANSIX962_EC_C2TNB191V3, | 63 SEC_OID_SECG_EC_SECP112R2, SEC_OID_SECG_EC_SECP128R1, |
67 SEC_OID_ANSIX962_EC_C2PNB208W1, | 64 SEC_OID_SECG_EC_SECP128R2, SEC_OID_SECG_EC_SECP160K1, |
68 SEC_OID_ANSIX962_EC_C2TNB239V1, | 65 SEC_OID_SECG_EC_SECP160R1, SEC_OID_SECG_EC_SECP160R2, |
69 SEC_OID_ANSIX962_EC_C2TNB239V2, | 66 SEC_OID_SECG_EC_SECP192K1, SEC_OID_SECG_EC_SECP224K1, |
70 SEC_OID_ANSIX962_EC_C2TNB239V3, | 67 SEC_OID_SECG_EC_SECP256K1, SEC_OID_SECG_EC_SECT113R1, |
71 SEC_OID_ANSIX962_EC_C2PNB272W1, | 68 SEC_OID_SECG_EC_SECT113R2, SEC_OID_SECG_EC_SECT131R1, |
72 SEC_OID_ANSIX962_EC_C2PNB304W1, | 69 SEC_OID_SECG_EC_SECT131R2, SEC_OID_SECG_EC_SECT163R1, |
73 SEC_OID_ANSIX962_EC_C2TNB359V1, | 70 SEC_OID_SECG_EC_SECT193R1, SEC_OID_SECG_EC_SECT193R2, |
74 SEC_OID_ANSIX962_EC_C2PNB368W1, | 71 SEC_OID_SECG_EC_SECT239K1, SEC_OID_UNKNOWN /* ECCurve_pastLastCurve */ |
75 SEC_OID_ANSIX962_EC_C2TNB431R1, | |
76 SEC_OID_SECG_EC_SECP112R1, | |
77 SEC_OID_SECG_EC_SECP112R2, | |
78 SEC_OID_SECG_EC_SECP128R1, | |
79 SEC_OID_SECG_EC_SECP128R2, | |
80 SEC_OID_SECG_EC_SECP160K1, | |
81 SEC_OID_SECG_EC_SECP160R1, | |
82 SEC_OID_SECG_EC_SECP160R2, | |
83 SEC_OID_SECG_EC_SECP192K1, | |
84 SEC_OID_SECG_EC_SECP224K1, | |
85 SEC_OID_SECG_EC_SECP256K1, | |
86 SEC_OID_SECG_EC_SECT113R1, | |
87 SEC_OID_SECG_EC_SECT113R2, | |
88 SEC_OID_SECG_EC_SECT131R1, | |
89 SEC_OID_SECG_EC_SECT131R2, | |
90 SEC_OID_SECG_EC_SECT163R1, | |
91 SEC_OID_SECG_EC_SECT193R1, | |
92 SEC_OID_SECG_EC_SECT193R2, | |
93 SEC_OID_SECG_EC_SECT239K1, | |
94 SEC_OID_UNKNOWN» /* ECCurve_pastLastCurve */ | |
95 }; | 72 }; |
96 | 73 |
97 typedef SECStatus (*op_func) (void *, void *, void *); | 74 typedef SECStatus (*op_func)(void *, void *, void *); |
98 typedef SECStatus (*pk11_op_func) (CK_SESSION_HANDLE, void *, void *, void *); | 75 typedef SECStatus (*pk11_op_func)(CK_SESSION_HANDLE, void *, void *, void *); |
99 | 76 |
100 typedef struct ThreadDataStr { | 77 typedef struct ThreadDataStr { |
101 op_func op; | 78 op_func op; |
102 void *p1; | 79 void *p1; |
103 void *p2; | 80 void *p2; |
104 void *p3; | 81 void *p3; |
105 int iters; | 82 int iters; |
106 PRLock *lock; | 83 PRLock *lock; |
107 int count; | 84 int count; |
108 SECStatus status; | 85 SECStatus status; |
109 int isSign; | 86 int isSign; |
110 } ThreadData; | 87 } ThreadData; |
111 | 88 |
112 void PKCS11Thread(void *data) | 89 void PKCS11Thread(void *data) { |
113 { | 90 ThreadData *threadData = (ThreadData *)data; |
114 ThreadData *threadData = (ThreadData *)data; | 91 pk11_op_func op = (pk11_op_func)threadData->op; |
115 pk11_op_func op = (pk11_op_func) threadData->op; | 92 int iters = threadData->iters; |
116 int iters = threadData->iters; | 93 unsigned char sigData[256]; |
117 unsigned char sigData [256]; | 94 SECItem sig; |
118 SECItem sig; | 95 CK_SESSION_HANDLE session; |
119 CK_SESSION_HANDLE session; | 96 CK_RV crv; |
120 CK_RV crv; | 97 |
121 | 98 threadData->status = SECSuccess; |
122 threadData->status = SECSuccess; | 99 threadData->count = 0; |
123 threadData->count = 0; | 100 |
124 | 101 /* get our thread's session */ |
125 /* get our thread's session */ | 102 PR_Lock(threadData->lock); |
126 PR_Lock(threadData->lock); | 103 crv = NSC_OpenSession(1, CKF_SERIAL_SESSION, NULL, 0, &session); |
127 crv = NSC_OpenSession(1, CKF_SERIAL_SESSION, NULL, 0, &session); | 104 PR_Unlock(threadData->lock); |
128 PR_Unlock(threadData->lock); | 105 |
129 | 106 if (threadData->isSign) { |
130 if (threadData->isSign) { | |
131 sig.data = sigData; | 107 sig.data = sigData; |
132 sig.len = sizeof(sigData); | 108 sig.len = sizeof(sigData); |
133 threadData->p2 = (void *)&sig; | 109 threadData->p2 = (void *)&sig; |
134 } | 110 } |
135 | 111 |
136 while (iters --) { | 112 while (iters--) { |
137 threadData->status = (*op)(session, threadData->p1, | 113 threadData->status = |
138 » threadData->p2, threadData->p3); | 114 (*op)(session, threadData->p1, threadData->p2, threadData->p3); |
139 if (threadData->status != SECSuccess) { | 115 if (threadData->status != SECSuccess) { |
140 » break; | 116 break; |
141 } | 117 } |
142 threadData->count++; | 118 threadData->count++; |
143 } | 119 } |
144 return; | 120 return; |
145 } | 121 } |
146 | 122 |
147 void genericThread(void *data) | 123 void genericThread(void *data) { |
148 { | 124 ThreadData *threadData = (ThreadData *)data; |
149 ThreadData *threadData = (ThreadData *)data; | 125 int iters = threadData->iters; |
150 int iters = threadData->iters; | 126 unsigned char sigData[256]; |
151 unsigned char sigData [256]; | 127 SECItem sig; |
152 SECItem sig; | 128 |
153 | 129 threadData->status = SECSuccess; |
154 threadData->status = SECSuccess; | 130 threadData->count = 0; |
155 threadData->count = 0; | 131 |
156 | 132 if (threadData->isSign) { |
157 if (threadData->isSign) { | |
158 sig.data = sigData; | 133 sig.data = sigData; |
159 sig.len = sizeof(sigData); | 134 sig.len = sizeof(sigData); |
160 threadData->p2 = (void *)&sig; | 135 threadData->p2 = (void *)&sig; |
161 } | 136 } |
162 | 137 |
163 while (iters --) { | 138 while (iters--) { |
164 threadData->status = (*threadData->op)(threadData->p1, | 139 threadData->status = |
165 » threadData->p2, threadData->p3); | 140 (*threadData->op)(threadData->p1, threadData->p2, threadData->p3); |
166 if (threadData->status != SECSuccess) { | 141 if (threadData->status != SECSuccess) { |
167 » break; | 142 break; |
168 } | 143 } |
169 threadData->count++; | 144 threadData->count++; |
170 } | 145 } |
171 return; | 146 return; |
172 } | 147 } |
173 | |
174 | 148 |
175 /* Time iter repetitions of operation op. */ | 149 /* Time iter repetitions of operation op. */ |
176 SECStatus | 150 SECStatus M_TimeOperation(void (*threadFunc)(void *), op_func opfunc, char *op, |
177 M_TimeOperation(void (*threadFunc)(void *), | 151 void *param1, void *param2, void *param3, int iters, |
178 » op_func opfunc, char *op, void *param1, void *param2, | 152 int numThreads, PRLock *lock, |
179 » void *param3, int iters, int numThreads, PRLock *lock,· | 153 CK_SESSION_HANDLE session, int isSign, double *rate) { |
180 » CK_SESSION_HANDLE session, int isSign, double *rate) | 154 double dUserTime; |
181 { | 155 int i, total; |
182 double dUserTime; | 156 PRIntervalTime startTime, totalTime; |
183 int i, total; | 157 PRThread **threadIDs; |
184 PRIntervalTime startTime, totalTime; | 158 ThreadData *threadData; |
185 PRThread **threadIDs; | 159 pk11_op_func pk11_op = (pk11_op_func)opfunc; |
186 ThreadData *threadData; | 160 SECStatus rv; |
187 pk11_op_func pk11_op = (pk11_op_func) opfunc; | 161 |
188 SECStatus rv; | 162 /* verify operation works before testing performance */ |
189 | 163 if (session) { |
190 /* verify operation works before testing performance */ | 164 rv = (*pk11_op)(session, param1, param2, param3); |
191 if (session) { | 165 } else { |
192 » rv = (*pk11_op)(session, param1, param2, param3); | 166 rv = (*opfunc)(param1, param2, param3); |
193 } else { | 167 } |
194 » rv = (*opfunc)(param1, param2, param3); | 168 if (rv != SECSuccess) { |
195 } | 169 SECU_PrintError("Error:", op); |
196 if (rv != SECSuccess) { | 170 return rv; |
197 » SECU_PrintError("Error:", op);· | 171 } |
198 » return rv; | 172 |
199 } | 173 /* get Data structures */ |
200 | 174 threadIDs = (PRThread **)PORT_Alloc(numThreads * sizeof(PRThread *)); |
201 /* get Data structures */ | 175 threadData = (ThreadData *)PORT_Alloc(numThreads * sizeof(ThreadData)); |
202 threadIDs = (PRThread **)PORT_Alloc(numThreads*sizeof(PRThread *));· | 176 |
203 threadData = (ThreadData *)PORT_Alloc(numThreads*sizeof(ThreadData)); | 177 startTime = PR_Now(); |
204 | 178 if (numThreads == 1) { |
205 startTime = PR_Now(); | 179 for (i = 0; i < iters; i++) { |
206 if (numThreads == 1) { | 180 if (session) { |
207 for (i=0; i < iters; i++) { | 181 rv = (*pk11_op)(session, param1, param2, param3); |
208 » if (session) { | 182 } else { |
209 » rv = (*pk11_op)(session, param1, param2, param3); | 183 rv = (*opfunc)(param1, param2, param3); |
210 » } else { | 184 } |
211 » rv = (*opfunc)(param1, param2, param3); | 185 } |
212 » } | 186 total = iters; |
213 } | 187 } else { |
214 » total = iters; | 188 for (i = 0; i < numThreads; i++) { |
215 } else { | 189 threadData[i].op = opfunc; |
216 » for (i = 0; i < numThreads; i++) { | 190 threadData[i].p1 = (void *)param1; |
217 » threadData[i].op = opfunc;· | 191 threadData[i].p2 = (void *)param2; |
218 » threadData[i].p1 = (void *)param1; | 192 threadData[i].p3 = (void *)param3; |
219 » threadData[i].p2 = (void *)param2; | 193 threadData[i].iters = iters; |
220 » threadData[i].p3 = (void *)param3; | 194 threadData[i].lock = lock; |
221 » threadData[i].iters = iters; | 195 threadData[i].isSign = isSign; |
222 » threadData[i].lock = lock; | 196 threadIDs[i] = PR_CreateThread(PR_USER_THREAD, threadFunc, |
223 » threadData[i].isSign = isSign; | 197 (void *)&threadData[i], PR_PRIORITY_NORMAL, |
224 » threadIDs[i] = PR_CreateThread(PR_USER_THREAD, threadFunc, | 198 PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); |
225 » (void *)&threadData[i], PR_PRIORITY_NORMAL, | 199 } |
226 » PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); | 200 |
227 » }· | 201 total = 0; |
228 | 202 for (i = 0; i < numThreads; i++) { |
229 » total = 0; | 203 PR_JoinThread(threadIDs[i]); |
230 » for (i = 0; i < numThreads; i++) { | 204 /* check the status */ |
231 » PR_JoinThread(threadIDs[i]); | 205 total += threadData[i].count; |
232 » /* check the status */ | 206 } |
233 » total += threadData[i].count; | 207 |
234 » } | 208 PORT_Free(threadIDs); |
235 | 209 PORT_Free(threadData); |
236 » PORT_Free(threadIDs); | 210 } |
237 » PORT_Free(threadData); | 211 |
238 } | 212 totalTime = PR_Now() - startTime; |
239 | 213 /* SecondsToInterval seems to be broken here ... */ |
240 totalTime = PR_Now()- startTime;· | 214 dUserTime = (double)totalTime / (double)1000000; |
241 /* SecondsToInterval seems to be broken here ... */ | 215 if (dUserTime) { |
242 dUserTime = (double)totalTime/(double)1000000; | 216 printf(" %-15s count:%4d sec: %3.2f op/sec: %6.2f\n", op, total, |
243 if (dUserTime) { | 217 dUserTime, (double)total / dUserTime); |
244 » printf(" %-15s count:%4d sec: %3.2f op/sec: %6.2f\n", | 218 if (rate) { |
245 » op, total, dUserTime, (double)total/dUserTime);· | 219 *rate = ((double)total) / dUserTime; |
246 » if (rate) { | 220 } |
247 » *rate = ((double)total)/dUserTime; | 221 } |
248 » } | 222 return SECSuccess; |
249 } | 223 } |
250 return SECSuccess; | 224 |
251 } | 225 #define GFP_POPULATE(params, name_v) \ |
252 | 226 params.name = name_v; \ |
253 #define GFP_POPULATE(params,name_v) \ | 227 if ((params.name < ECCurve_noName) || (params.name > ECCurve_pastLastCurve)) \ |
254 params.name = name_v; \ | 228 goto cleanup; \ |
255 if ((params.name < ECCurve_noName) || \ | 229 params.type = ec_params_named; \ |
256 » (params.name > ECCurve_pastLastCurve)) goto cleanup; \ | 230 params.curveOID.data = NULL; \ |
257 params.type = ec_params_named; \ | 231 params.curveOID.len = 0; \ |
258 params.curveOID.data = NULL; \ | 232 params.curve.seed.data = NULL; \ |
259 params.curveOID.len = 0; \ | 233 params.curve.seed.len = 0; \ |
260 params.curve.seed.data = NULL; \ | 234 params.DEREncoding.data = NULL; \ |
261 params.curve.seed.len = 0; \ | 235 params.DEREncoding.len = 0; \ |
262 params.DEREncoding.data = NULL; \ | 236 params.arena = NULL; \ |
263 params.DEREncoding.len = 0; \ | 237 params.fieldID.size = ecCurve_map[name_v]->size; \ |
264 params.arena = NULL; \ | 238 params.fieldID.type = ec_field_GFp; \ |
265 params.fieldID.size = ecCurve_map[name_v]->size; \ | 239 hexString2SECItem(params.arena, ¶ms.fieldID.u.prime, \ |
266 params.fieldID.type = ec_field_GFp; \ | 240 ecCurve_map[name_v]->irr); \ |
267 hexString2SECItem(params.arena, ¶ms.fieldID.u.prime, \ | 241 hexString2SECItem(params.arena, ¶ms.curve.a, \ |
268 » ecCurve_map[name_v]->irr); \ | 242 ecCurve_map[name_v]->curvea); \ |
269 hexString2SECItem(params.arena, ¶ms.curve.a, \ | 243 hexString2SECItem(params.arena, ¶ms.curve.b, \ |
270 » ecCurve_map[name_v]->curvea); \ | 244 ecCurve_map[name_v]->curveb); \ |
271 hexString2SECItem(params.arena, ¶ms.curve.b, \ | 245 genenc[0] = '0'; \ |
272 » ecCurve_map[name_v]->curveb); \ | 246 genenc[1] = '4'; \ |
273 genenc[0] = '0'; \ | 247 genenc[2] = '\0'; \ |
274 genenc[1] = '4'; \ | 248 strcat(genenc, ecCurve_map[name_v]->genx); \ |
275 genenc[2] = '\0'; \ | 249 strcat(genenc, ecCurve_map[name_v]->geny); \ |
276 strcat(genenc, ecCurve_map[name_v]->genx); \ | 250 hexString2SECItem(params.arena, ¶ms.base, genenc); \ |
277 strcat(genenc, ecCurve_map[name_v]->geny); \ | 251 hexString2SECItem(params.arena, ¶ms.order, ecCurve_map[name_v]->order); \ |
278 hexString2SECItem(params.arena, ¶ms.base, \ | 252 params.cofactor = ecCurve_map[name_v]->cofactor; |
279 » genenc); \ | |
280 hexString2SECItem(params.arena, ¶ms.order, \ | |
281 » ecCurve_map[name_v]->order); \ | |
282 params.cofactor = ecCurve_map[name_v]->cofactor; | |
283 | |
284 | 253 |
285 /* Test curve using specific field arithmetic. */ | 254 /* Test curve using specific field arithmetic. */ |
286 #define ECTEST_NAMED_GFP(name_c, name_v) \ | 255 #define ECTEST_NAMED_GFP(name_c, name_v) \ |
287 if (usefreebl) { \ | 256 if (usefreebl) { \ |
288 » printf("Testing %s using freebl implementation...\n", name_c); \ | 257 printf("Testing %s using freebl implementation...\n", name_c); \ |
289 » rv = ectest_curve_freebl(name_v, iterations, numThreads); \ | 258 rv = ectest_curve_freebl(name_v, iterations, numThreads); \ |
290 » if (rv != SECSuccess) goto cleanup; \ | 259 if (rv != SECSuccess) goto cleanup; \ |
291 » printf("... okay.\n"); \ | 260 printf("... okay.\n"); \ |
292 » } \ | 261 } \ |
293 if (usepkcs11) { \ | 262 if (usepkcs11) { \ |
294 » printf("Testing %s using pkcs11 implementation...\n", name_c); \ | 263 printf("Testing %s using pkcs11 implementation...\n", name_c); \ |
295 » rv = ectest_curve_pkcs11(name_v, iterations, numThreads); \ | 264 rv = ectest_curve_pkcs11(name_v, iterations, numThreads); \ |
296 » if (rv != SECSuccess) goto cleanup; \ | 265 if (rv != SECSuccess) goto cleanup; \ |
297 » printf("... okay.\n"); \ | 266 printf("... okay.\n"); \ |
298 } | 267 } |
299 | 268 |
300 /* | 269 /* |
301 * Initializes a SECItem from a hexadecimal string | 270 * Initializes a SECItem from a hexadecimal string |
302 * | 271 * |
303 * Warning: This function ignores leading 00's, so any leading 00's | 272 * Warning: This function ignores leading 00's, so any leading 00's |
304 * in the hexadecimal string must be optional. | 273 * in the hexadecimal string must be optional. |
305 */ | 274 */ |
306 static SECItem * | 275 static SECItem *hexString2SECItem(PLArenaPool *arena, SECItem *item, |
307 hexString2SECItem(PLArenaPool *arena, SECItem *item, const char *str) | 276 const char *str) { |
308 { | 277 int i = 0; |
309 int i = 0; | 278 int byteval = 0; |
310 int byteval = 0; | 279 int tmp = PORT_Strlen(str); |
311 int tmp = PORT_Strlen(str); | 280 |
312 | 281 if ((tmp % 2) != 0) return NULL; |
313 if ((tmp % 2) != 0) return NULL; | 282 |
314 ···· | 283 /* skip leading 00's unless the hex string is "00" */ |
315 /* skip leading 00's unless the hex string is "00" */ | 284 while ((tmp > 2) && (str[0] == '0') && (str[1] == '0')) { |
316 while ((tmp > 2) && (str[0] == '0') && (str[1] == '0')) { | 285 str += 2; |
317 » str += 2; | 286 tmp -= 2; |
318 » tmp -= 2; | 287 } |
319 } | 288 |
320 | 289 item->data = (unsigned char *)PORT_Alloc(tmp / 2); |
321 item->data = (unsigned char *) PORT_Alloc( tmp/2); | 290 if (item->data == NULL) return NULL; |
322 if (item->data == NULL) return NULL; | 291 item->len = tmp / 2; |
323 item->len = tmp/2; | 292 |
324 | 293 while (str[i]) { |
325 while (str[i]) { | 294 if ((str[i] >= '0') && (str[i] <= '9')) |
326 » if ((str[i] >= '0') && (str[i] <= '9')) | 295 tmp = str[i] - '0'; |
327 » tmp = str[i] - '0'; | 296 else if ((str[i] >= 'a') && (str[i] <= 'f')) |
328 » else if ((str[i] >= 'a') && (str[i] <= 'f')) | 297 tmp = str[i] - 'a' + 10; |
329 » tmp = str[i] - 'a' + 10; | 298 else if ((str[i] >= 'A') && (str[i] <= 'F')) |
330 » else if ((str[i] >= 'A') && (str[i] <= 'F')) | 299 tmp = str[i] - 'A' + 10; |
331 » tmp = str[i] - 'A' + 10; | 300 else |
332 » else | 301 return NULL; |
333 » return NULL; | 302 |
334 | 303 byteval = byteval * 16 + tmp; |
335 » byteval = byteval * 16 + tmp; | 304 if ((i % 2) != 0) { |
336 » if ((i % 2) != 0) { | 305 item->data[i / 2] = byteval; |
337 » item->data[i/2] = byteval; | 306 byteval = 0; |
338 » byteval = 0; | 307 } |
339 » } | 308 i++; |
340 » i++; | 309 } |
341 } | 310 |
342 | 311 return item; |
343 return item; | 312 } |
344 } | 313 |
345 | 314 #define PK11_SETATTRS(x, id, v, l) \ |
346 #define PK11_SETATTRS(x,id,v,l) (x)->type = (id); \ | 315 (x)->type = (id); \ |
347 » » (x)->pValue=(v); (x)->ulValueLen = (l); | 316 (x)->pValue = (v); \ |
348 | 317 (x)->ulValueLen = (l); |
349 | 318 |
350 SECStatus | 319 SECStatus PKCS11_Derive(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hKey, |
351 PKCS11_Derive(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hKey,· | 320 CK_MECHANISM *pMech, int *dummy) { |
352 » CK_MECHANISM *pMech , int *dummy) | 321 CK_RV crv; |
353 { | 322 CK_OBJECT_HANDLE newKey; |
354 CK_RV crv; | 323 CK_BBOOL cktrue = CK_TRUE; |
355 CK_OBJECT_HANDLE newKey; | 324 CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; |
356 CK_BBOOL cktrue = CK_TRUE; | 325 CK_KEY_TYPE keyType = CKK_GENERIC_SECRET; |
357 CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; | 326 CK_ATTRIBUTE keyTemplate[3]; |
358 CK_KEY_TYPE keyType = CKK_GENERIC_SECRET; | 327 CK_ATTRIBUTE *attrs = keyTemplate; |
359 CK_ATTRIBUTE keyTemplate[3]; | 328 |
360 CK_ATTRIBUTE *attrs = keyTemplate; | 329 PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass)); |
361 | 330 attrs++; |
362 PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass)); | 331 PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType)); |
363 attrs++; | 332 attrs++; |
364 PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType)); | 333 PK11_SETATTRS(attrs, CKA_DERIVE, &cktrue, 1); |
365 attrs++; | 334 attrs++; |
366 PK11_SETATTRS(attrs, CKA_DERIVE, &cktrue, 1); attrs++; | 335 |
367 | 336 crv = NSC_DeriveKey(session, pMech, *hKey, keyTemplate, 3, &newKey); |
368 | 337 if (crv != CKR_OK) { |
369 crv = NSC_DeriveKey(session, pMech, *hKey, keyTemplate, 3, &newKey); | 338 printf("Derive Failed CK_RV=0x%x\n", (int)crv); |
370 if (crv != CKR_OK) { | 339 return SECFailure; |
371 » printf("Derive Failed CK_RV=0x%x\n", (int)crv); | 340 } |
372 » return SECFailure; | 341 return SECSuccess; |
373 } | 342 } |
374 return SECSuccess; | 343 |
375 } | 344 SECStatus PKCS11_Sign(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hKey, |
376 | 345 SECItem *sig, SECItem *digest) { |
377 SECStatus | 346 CK_RV crv; |
378 PKCS11_Sign(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hKey,· | 347 CK_MECHANISM mech; |
379 » SECItem *sig, SECItem *digest) | 348 |
380 { | 349 mech.mechanism = CKM_ECDSA; |
381 CK_RV crv; | 350 mech.pParameter = NULL; |
382 CK_MECHANISM mech; | 351 mech.ulParameterLen = 0; |
383 | 352 |
384 mech.mechanism = CKM_ECDSA; | 353 crv = NSC_SignInit(session, &mech, *hKey); |
385 mech.pParameter = NULL; | 354 if (crv != CKR_OK) { |
386 mech.ulParameterLen = 0; | |
387 | |
388 crv = NSC_SignInit(session, &mech, *hKey); | |
389 if (crv != CKR_OK) { | |
390 printf("Sign Failed CK_RV=0x%x\n", (int)crv); | 355 printf("Sign Failed CK_RV=0x%x\n", (int)crv); |
391 return SECFailure; | 356 return SECFailure; |
392 } | 357 } |
393 crv = NSC_Sign(session, digest->data, digest->len, sig->data,· | 358 crv = NSC_Sign(session, digest->data, digest->len, sig->data, |
394 » (CK_ULONG_PTR)&sig->len); | 359 (CK_ULONG_PTR) & sig->len); |
395 if (crv != CKR_OK) { | 360 if (crv != CKR_OK) { |
396 printf("Sign Failed CK_RV=0x%x\n", (int)crv); | 361 printf("Sign Failed CK_RV=0x%x\n", (int)crv); |
397 return SECFailure; | 362 return SECFailure; |
398 } | 363 } |
399 return SECSuccess; | 364 return SECSuccess; |
400 } | 365 } |
401 | 366 |
402 SECStatus | 367 SECStatus PKCS11_Verify(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hKey, |
403 PKCS11_Verify(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hKey,· | 368 SECItem *sig, SECItem *digest) { |
404 » SECItem *sig, SECItem *digest) | 369 CK_RV crv; |
405 { | 370 CK_MECHANISM mech; |
406 CK_RV crv; | 371 |
407 CK_MECHANISM mech; | 372 mech.mechanism = CKM_ECDSA; |
408 | 373 mech.pParameter = NULL; |
409 mech.mechanism = CKM_ECDSA; | 374 mech.ulParameterLen = 0; |
410 mech.pParameter = NULL; | 375 |
411 mech.ulParameterLen = 0; | 376 crv = NSC_VerifyInit(session, &mech, *hKey); |
412 | 377 if (crv != CKR_OK) { |
413 crv = NSC_VerifyInit(session, &mech, *hKey); | |
414 if (crv != CKR_OK) { | |
415 printf("Verify Failed CK_RV=0x%x\n", (int)crv); | 378 printf("Verify Failed CK_RV=0x%x\n", (int)crv); |
416 return SECFailure; | 379 return SECFailure; |
417 } | 380 } |
418 crv = NSC_Verify(session, digest->data, digest->len, sig->data, sig->len); | 381 crv = NSC_Verify(session, digest->data, digest->len, sig->data, sig->len); |
419 if (crv != CKR_OK) { | 382 if (crv != CKR_OK) { |
420 printf("Verify Failed CK_RV=0x%x\n", (int)crv); | 383 printf("Verify Failed CK_RV=0x%x\n", (int)crv); |
421 return SECFailure; | 384 return SECFailure; |
422 } | 385 } |
423 return SECSuccess; | 386 return SECSuccess; |
424 } | 387 } |
425 | 388 |
426 static SECStatus | 389 static SECStatus ecName2params(ECCurveName curve, SECKEYECParams *params) { |
427 ecName2params(ECCurveName curve, SECKEYECParams * params) | 390 SECOidData *oidData = NULL; |
428 { | 391 |
429 SECOidData *oidData = NULL; | 392 if ((curve < ECCurve_noName) || (curve > ECCurve_pastLastCurve) || |
430 | 393 ((oidData = SECOID_FindOIDByTag(ecCurve_oid_map[curve])) == NULL)) { |
431 if ((curve < ECCurve_noName) || (curve > ECCurve_pastLastCurve) || | 394 PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE); |
432 » ((oidData = SECOID_FindOIDByTag(ecCurve_oid_map[curve])) == NULL)) { | 395 return SECFailure; |
433 » PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE); | 396 } |
434 » return SECFailure; | 397 |
435 } | 398 SECITEM_AllocItem(NULL, params, (2 + oidData->oid.len)); |
436 | 399 /* |
437 SECITEM_AllocItem(NULL, params, (2 + oidData->oid.len)); | 400 * params->data needs to contain the ASN encoding of an object ID (OID) |
438 /* | 401 * representing the named curve. The actual OID is in |
439 * params->data needs to contain the ASN encoding of an object ID (OID) | 402 * oidData->oid.data so we simply prepend 0x06 and OID length |
440 * representing the named curve. The actual OID is in | 403 */ |
441 * oidData->oid.data so we simply prepend 0x06 and OID length | 404 params->data[0] = SEC_ASN1_OBJECT_ID; |
442 */ | 405 params->data[1] = oidData->oid.len; |
443 params->data[0] = SEC_ASN1_OBJECT_ID; | 406 memcpy(params->data + 2, oidData->oid.data, oidData->oid.len); |
444 params->data[1] = oidData->oid.len; | 407 |
445 memcpy(params->data + 2, oidData->oid.data, oidData->oid.len); | 408 return SECSuccess; |
446 | 409 } |
447 return SECSuccess; | |
448 } | |
449 | |
450 | |
451 | 410 |
452 /* Performs basic tests of elliptic curve cryptography over prime fields. | 411 /* Performs basic tests of elliptic curve cryptography over prime fields. |
453 * If tests fail, then it prints an error message, aborts, and returns an | 412 * If tests fail, then it prints an error message, aborts, and returns an |
454 * error code. Otherwise, returns 0. */ | 413 * error code. Otherwise, returns 0. */ |
455 SECStatus | 414 SECStatus ectest_curve_pkcs11(ECCurveName curve, int iterations, |
456 ectest_curve_pkcs11(ECCurveName curve, int iterations, int numThreads) | 415 int numThreads) { |
457 { | 416 CK_OBJECT_HANDLE ecPriv; |
458 CK_OBJECT_HANDLE ecPriv; | 417 CK_OBJECT_HANDLE ecPub; |
459 CK_OBJECT_HANDLE ecPub; | 418 CK_SESSION_HANDLE session; |
460 CK_SESSION_HANDLE session; | 419 SECItem sig; |
461 SECItem sig; | 420 SECItem digest; |
462 SECItem digest; | 421 SECKEYECParams ecParams; |
463 SECKEYECParams ecParams; | 422 CK_MECHANISM mech; |
464 CK_MECHANISM mech; | 423 CK_ECDH1_DERIVE_PARAMS ecdh_params; |
465 CK_ECDH1_DERIVE_PARAMS ecdh_params; | 424 unsigned char sigData[256]; |
466 unsigned char sigData [256]; | 425 unsigned char digestData[20]; |
467 unsigned char digestData[20]; | 426 unsigned char pubKeyData[256]; |
468 unsigned char pubKeyData[256]; | 427 PRLock *lock = NULL; |
469 PRLock *lock = NULL; | 428 double signRate, deriveRate; |
470 double signRate, deriveRate; | 429 CK_ATTRIBUTE template; |
471 CK_ATTRIBUTE template; | 430 SECStatus rv; |
472 SECStatus rv; | 431 CK_RV crv; |
473 CK_RV crv; | 432 |
474 | 433 ecParams.data = NULL; |
475 ecParams.data = NULL; | 434 ecParams.len = 0; |
476 ecParams.len = 0; | 435 rv = ecName2params(curve, &ecParams); |
477 rv = ecName2params(curve, &ecParams); | 436 if (rv != SECSuccess) { |
478 if (rv != SECSuccess) { | |
479 goto cleanup; | 437 goto cleanup; |
480 } | 438 } |
481 | 439 |
482 crv = NSC_OpenSession(1, CKF_SERIAL_SESSION, NULL, 0, &session); | 440 crv = NSC_OpenSession(1, CKF_SERIAL_SESSION, NULL, 0, &session); |
483 if (crv != CKR_OK) { | 441 if (crv != CKR_OK) { |
484 printf("OpenSession Failed CK_RV=0x%x\n", (int)crv); | 442 printf("OpenSession Failed CK_RV=0x%x\n", (int)crv); |
485 return SECFailure; | 443 return SECFailure; |
486 } | 444 } |
487 | 445 |
488 PORT_Memset(digestData, 0xa5, sizeof(digestData)); | 446 PORT_Memset(digestData, 0xa5, sizeof(digestData)); |
489 digest.data = digestData; | 447 digest.data = digestData; |
490 digest.len = sizeof(digestData); | 448 digest.len = sizeof(digestData); |
491 sig.data = sigData; | 449 sig.data = sigData; |
492 sig.len = sizeof(sigData); | 450 sig.len = sizeof(sigData); |
493 | 451 |
494 template.type = CKA_EC_PARAMS; | 452 template.type = CKA_EC_PARAMS; |
495 template.pValue = ecParams.data; | 453 template.pValue = ecParams.data; |
496 template.ulValueLen = ecParams.len; | 454 template.ulValueLen = ecParams.len; |
497 mech.mechanism = CKM_EC_KEY_PAIR_GEN; | 455 mech.mechanism = CKM_EC_KEY_PAIR_GEN; |
498 mech.pParameter = NULL; | 456 mech.pParameter = NULL; |
499 mech.ulParameterLen = 0; | 457 mech.ulParameterLen = 0; |
500 crv = NSC_GenerateKeyPair(session, &mech, | 458 crv = NSC_GenerateKeyPair(session, &mech, &template, 1, NULL, 0, &ecPub, |
501 » » &template, 1, NULL, 0, &ecPub, &ecPriv); | 459 &ecPriv); |
502 if (crv != CKR_OK) { | 460 if (crv != CKR_OK) { |
503 printf("GenerateKeyPair Failed CK_RV=0x%x\n", (int)crv); | 461 printf("GenerateKeyPair Failed CK_RV=0x%x\n", (int)crv); |
504 return SECFailure; | 462 return SECFailure; |
505 } | 463 } |
506 | 464 |
507 template.type = CKA_EC_POINT; | 465 template.type = CKA_EC_POINT; |
508 template.pValue = pubKeyData; | 466 template.pValue = pubKeyData; |
509 template.ulValueLen = sizeof(pubKeyData); | 467 template.ulValueLen = sizeof(pubKeyData); |
510 crv = NSC_GetAttributeValue(session, ecPub, &template, 1); | 468 crv = NSC_GetAttributeValue(session, ecPub, &template, 1); |
511 if (crv != CKR_OK) { | 469 if (crv != CKR_OK) { |
512 printf("GenerateKeyPair Failed CK_RV=0x%x\n", (int)crv); | 470 printf("GenerateKeyPair Failed CK_RV=0x%x\n", (int)crv); |
513 return SECFailure; | 471 return SECFailure; |
514 } | 472 } |
515 | 473 |
516 ecdh_params.kdf = CKD_NULL; | 474 ecdh_params.kdf = CKD_NULL; |
517 ecdh_params.ulSharedDataLen = 0; | 475 ecdh_params.ulSharedDataLen = 0; |
518 ecdh_params.pSharedData = NULL; | 476 ecdh_params.pSharedData = NULL; |
519 ecdh_params.ulPublicDataLen = template.ulValueLen; | 477 ecdh_params.ulPublicDataLen = template.ulValueLen; |
520 ecdh_params.pPublicData = template.pValue; | 478 ecdh_params.pPublicData = template.pValue; |
521 | 479 |
522 mech.mechanism = CKM_ECDH1_DERIVE; | 480 mech.mechanism = CKM_ECDH1_DERIVE; |
523 mech.pParameter = (void *)&ecdh_params; | 481 mech.pParameter = (void *)&ecdh_params; |
524 mech.ulParameterLen = sizeof(ecdh_params); | 482 mech.ulParameterLen = sizeof(ecdh_params); |
525 | 483 |
526 lock = PR_NewLock(); | 484 lock = PR_NewLock(); |
527 | 485 |
528 rv = M_TimeOperation(PKCS11Thread, (op_func)PKCS11_Derive, "ECDH_Derive", | 486 rv = M_TimeOperation(PKCS11Thread, (op_func)PKCS11_Derive, "ECDH_Derive", |
529 » &ecPriv, &mech, NULL, iterations, numThreads, | 487 &ecPriv, &mech, NULL, iterations, numThreads, lock, |
530 » lock, session, 0, &deriveRate); | 488 session, 0, &deriveRate); |
531 if (rv != SECSuccess) goto cleanup; | 489 if (rv != SECSuccess) goto cleanup; |
532 rv = M_TimeOperation(PKCS11Thread, (op_func)PKCS11_Sign, "ECDSA_Sign", | 490 rv = M_TimeOperation(PKCS11Thread, (op_func)PKCS11_Sign, "ECDSA_Sign", |
533 » (void *)&ecPriv, &sig, &digest, iterations, numThreads, | 491 (void *)&ecPriv, &sig, &digest, iterations, numThreads, |
534 » lock, session, 1, &signRate); | 492 lock, session, 1, &signRate); |
535 if (rv != SECSuccess) goto cleanup; | 493 if (rv != SECSuccess) goto cleanup; |
536 printf(" ECDHE max rate = %.2f\n", (deriveRate+signRate)/4.0); | 494 printf(" ECDHE max rate = %.2f\n", (deriveRate + signRate) / 4.0); |
537 /* get a signature */ | 495 /* get a signature */ |
538 rv = PKCS11_Sign(session, &ecPriv, &sig, &digest); | 496 rv = PKCS11_Sign(session, &ecPriv, &sig, &digest); |
539 if (rv != SECSuccess) goto cleanup; | 497 if (rv != SECSuccess) goto cleanup; |
540 rv = M_TimeOperation(PKCS11Thread, (op_func)PKCS11_Verify, "ECDSA_Verify", | 498 rv = M_TimeOperation(PKCS11Thread, (op_func)PKCS11_Verify, "ECDSA_Verify", |
541 » (void *)&ecPub, &sig, &digest, iterations, numThreads, | 499 (void *)&ecPub, &sig, &digest, iterations, numThreads, |
542 » lock, session, 0, NULL); | 500 lock, session, 0, NULL); |
543 if (rv != SECSuccess) goto cleanup; | 501 if (rv != SECSuccess) goto cleanup; |
544 | 502 |
545 cleanup: | 503 cleanup: |
546 if (lock) { | 504 if (lock) { |
547 PR_DestroyLock(lock); | 505 PR_DestroyLock(lock); |
548 } | 506 } |
549 return rv; | 507 return rv; |
550 } | 508 } |
551 | 509 |
552 SECStatus | 510 SECStatus ECDH_DeriveWrap(ECPrivateKey *priv, ECPublicKey *pub, int *dummy) { |
553 ECDH_DeriveWrap(ECPrivateKey *priv, ECPublicKey *pub, int *dummy) | 511 SECItem secret; |
554 { | 512 unsigned char secretData[256]; |
555 SECItem secret; | 513 SECStatus rv; |
556 unsigned char secretData[256]; | 514 |
557 SECStatus rv; | 515 secret.data = secretData; |
558 | 516 secret.len = sizeof(secretData); |
559 secret.data = secretData; | 517 |
560 secret.len = sizeof(secretData); | 518 rv = ECDH_Derive(&pub->publicValue, &pub->ecParams, &priv->privateValue, 0, |
561 | 519 &secret); |
562 rv = ECDH_Derive(&pub->publicValue, &pub->ecParams, | |
563 » &priv->privateValue, 0, &secret); | |
564 #ifdef notdef | 520 #ifdef notdef |
565 if (rv == SECSuccess) { | 521 if (rv == SECSuccess) { |
566 PORT_Free(secret.data); | 522 PORT_Free(secret.data); |
567 } | 523 } |
568 #endif | 524 #endif |
569 return rv; | 525 return rv; |
570 } | 526 } |
571 | 527 |
572 /* Performs basic tests of elliptic curve cryptography over prime fields. | 528 /* Performs basic tests of elliptic curve cryptography over prime fields. |
573 * If tests fail, then it prints an error message, aborts, and returns an | 529 * If tests fail, then it prints an error message, aborts, and returns an |
574 * error code. Otherwise, returns 0. */ | 530 * error code. Otherwise, returns 0. */ |
575 SECStatus | 531 SECStatus ectest_curve_freebl(ECCurveName curve, int iterations, |
576 ectest_curve_freebl(ECCurveName curve, int iterations, int numThreads) | 532 int numThreads) { |
577 { | 533 ECParams ecParams; |
578 ECParams ecParams; | 534 ECPrivateKey *ecPriv = NULL; |
579 ECPrivateKey *ecPriv = NULL; | 535 ECPublicKey ecPub; |
580 ECPublicKey ecPub; | 536 SECItem sig; |
581 SECItem sig; | 537 SECItem digest; |
582 SECItem digest; | 538 unsigned char sigData[256]; |
583 unsigned char sigData [256]; | 539 unsigned char digestData[20]; |
584 unsigned char digestData[20]; | 540 double signRate, deriveRate; |
585 double signRate, deriveRate; | 541 char genenc[3 + 2 * 2 * MAX_ECKEY_LEN]; |
586 char genenc[3 + 2 * 2 * MAX_ECKEY_LEN]; | 542 SECStatus rv; |
587 SECStatus rv; | 543 |
588 | 544 GFP_POPULATE(ecParams, curve); |
589 | 545 |
590 GFP_POPULATE(ecParams, curve); | 546 PORT_Memset(digestData, 0xa5, sizeof(digestData)); |
591 | 547 digest.data = digestData; |
592 PORT_Memset(digestData, 0xa5, sizeof(digestData)); | 548 digest.len = sizeof(digestData); |
593 digest.data = digestData; | 549 sig.data = sigData; |
594 digest.len = sizeof(digestData); | 550 sig.len = sizeof(sigData); |
595 sig.data = sigData; | 551 |
596 sig.len = sizeof(sigData); | 552 rv = EC_NewKey(&ecParams, &ecPriv); |
597 | 553 if (rv != SECSuccess) { |
598 rv = EC_NewKey(&ecParams, &ecPriv); | 554 return SECFailure; |
599 if (rv != SECSuccess) { | 555 } |
600 return SECFailure; | 556 ecPub.ecParams = ecParams; |
601 } | 557 ecPub.publicValue = ecPriv->publicValue; |
602 ecPub.ecParams = ecParams; | 558 |
603 ecPub.publicValue = ecPriv->publicValue; | 559 M_TimeOperation(genericThread, (op_func)ECDH_DeriveWrap, "ECDH_Derive", |
604 | 560 ecPriv, &ecPub, NULL, iterations, numThreads, 0, 0, 0, |
605 M_TimeOperation(genericThread, (op_func) ECDH_DeriveWrap, "ECDH_Derive", | 561 &deriveRate); |
606 » ecPriv, &ecPub, NULL, iterations, numThreads, 0, 0, 0, &deriveRate); | 562 if (rv != SECSuccess) goto cleanup; |
607 if (rv != SECSuccess) goto cleanup; | 563 M_TimeOperation(genericThread, (op_func)ECDSA_SignDigest, "ECDSA_Sign", |
608 M_TimeOperation(genericThread, (op_func) ECDSA_SignDigest, "ECDSA_Sign", | 564 ecPriv, &sig, &digest, iterations, numThreads, 0, 0, 1, |
609 » ecPriv, &sig, &digest, iterations, numThreads, 0, 0, 1, &signRate); | 565 &signRate); |
610 if (rv != SECSuccess) goto cleanup; | 566 if (rv != SECSuccess) goto cleanup; |
611 printf(" ECDHE max rate = %.2f\n", (deriveRate+signRate)/4.0); | 567 printf(" ECDHE max rate = %.2f\n", (deriveRate + signRate) / 4.0); |
612 rv = ECDSA_SignDigest(ecPriv, &sig, &digest); | 568 rv = ECDSA_SignDigest(ecPriv, &sig, &digest); |
613 if (rv != SECSuccess) goto cleanup; | 569 if (rv != SECSuccess) goto cleanup; |
614 M_TimeOperation(genericThread, (op_func) ECDSA_VerifyDigest, "ECDSA_Verify", | 570 M_TimeOperation(genericThread, (op_func)ECDSA_VerifyDigest, "ECDSA_Verify", |
615 » &ecPub, &sig, &digest, iterations, numThreads, 0, 0, 0, NULL); | 571 &ecPub, &sig, &digest, iterations, numThreads, 0, 0, 0, NULL); |
616 if (rv != SECSuccess) goto cleanup; | 572 if (rv != SECSuccess) goto cleanup; |
617 | 573 |
618 cleanup: | 574 cleanup: |
619 return rv; | 575 return rv; |
620 } | 576 } |
621 | 577 |
622 /* Prints help information. */ | 578 /* Prints help information. */ |
623 void | 579 void printUsage(char *prog) { |
624 printUsage(char *prog) | 580 printf("Usage: %s [-i iterations] [-t threads ] [-ans] [-fp] [-A]\n", prog); |
625 { | |
626 printf("Usage: %s [-i iterations] [-t threads ] [-ans] [-fp] [-A]\n",prog); | |
627 } | 581 } |
628 | 582 |
629 /* Performs tests of elliptic curve cryptography over prime fields If | 583 /* Performs tests of elliptic curve cryptography over prime fields If |
630 * tests fail, then it prints an error message, aborts, and returns an | 584 * tests fail, then it prints an error message, aborts, and returns an |
631 * error code. Otherwise, returns 0. */ | 585 * error code. Otherwise, returns 0. */ |
632 int | 586 int main(int argv, char **argc) { |
633 main(int argv, char **argc) | 587 int ansi = 0; |
634 { | 588 int nist = 0; |
635 int ansi = 0; | 589 int secp = 0; |
636 int nist = 0; | 590 int usefreebl = 0; |
637 int secp = 0; | 591 int usepkcs11 = 0; |
638 int usefreebl = 0; | 592 int i; |
639 int usepkcs11 = 0; | 593 SECStatus rv = SECSuccess; |
640 int i; | 594 int iterations = 100; |
641 SECStatus rv = SECSuccess; | 595 int numThreads = 1; |
642 int iterations = 100; | 596 |
643 int numThreads = 1; | 597 /* read command-line arguments */ |
644 | 598 for (i = 1; i < argv; i++) { |
645 /* read command-line arguments */ | 599 if (strcasecmp(argc[i], "-i") == 0) { |
646 for (i = 1; i < argv; i++) { | 600 i++; |
647 » if (strcasecmp(argc[i], "-i") == 0) { | 601 iterations = atoi(argc[i]); |
648 » i++; | 602 } else if (strcasecmp(argc[i], "-t") == 0) { |
649 » iterations = atoi(argc[i]); | 603 i++; |
650 » } else if (strcasecmp(argc[i], "-t") == 0) { | 604 numThreads = atoi(argc[i]); |
651 » i++; | 605 } else if (strcasecmp(argc[i], "-A") == 0) { |
652 » numThreads = atoi(argc[i]); | 606 ansi = nist = secp = 1; |
653 » } else if (strcasecmp(argc[i], "-A") == 0) { | 607 usepkcs11 = usefreebl = 1; |
654 » ansi = nist = secp = 1; | 608 } else if (strcasecmp(argc[i], "-a") == 0) { |
655 » usepkcs11 = usefreebl = 1; | 609 ansi = 1; |
656 » } else if (strcasecmp(argc[i], "-a") == 0) { | 610 } else if (strcasecmp(argc[i], "-n") == 0) { |
657 » ansi = 1; | 611 nist = 1; |
658 » } else if (strcasecmp(argc[i], "-n") == 0) { | 612 } else if (strcasecmp(argc[i], "-s") == 0) { |
659 » nist = 1; | 613 secp = 1; |
660 » } else if (strcasecmp(argc[i], "-s") == 0) { | 614 } else if (strcasecmp(argc[i], "-p") == 0) { |
661 » secp = 1; | 615 usepkcs11 = 1; |
662 » } else if (strcasecmp(argc[i], "-p") == 0) { | 616 } else if (strcasecmp(argc[i], "-f") == 0) { |
663 » usepkcs11 = 1; | 617 usefreebl = 1; |
664 » } else if (strcasecmp(argc[i], "-f") == 0) { | 618 } else { |
665 » usefreebl = 1; | 619 printUsage(argc[0]); |
666 » } else { | 620 return 0; |
667 » printUsage(argc[0]); | 621 } |
668 » return 0; | 622 } |
669 » } | 623 |
670 } | 624 if ((ansi | nist | secp) == 0) { |
671 | 625 nist = 1; |
672 if ((ansi | nist | secp) == 0) { | 626 } |
673 » nist = 1; | 627 if ((usepkcs11 | usefreebl) == 0) { |
674 } | 628 usefreebl = 1; |
675 if ((usepkcs11|usefreebl) == 0) { | 629 } |
676 » usefreebl = 1; | 630 |
677 } | 631 rv = NSS_NoDB_Init(NULL); |
678 | 632 if (rv != SECSuccess) { |
679 rv = NSS_NoDB_Init(NULL); | 633 SECU_PrintError("Error:", "NSS_NoDB_Init"); |
680 if (rv != SECSuccess) { | 634 goto cleanup; |
681 » SECU_PrintError("Error:", "NSS_NoDB_Init");· | 635 } |
682 » goto cleanup; | 636 |
683 } | 637 /* specific arithmetic tests */ |
684 | 638 if (nist) { |
685 /* specific arithmetic tests */ | 639 ECTEST_NAMED_GFP("SECP-160K1", ECCurve_SECG_PRIME_160K1); |
686 if (nist) { | 640 ECTEST_NAMED_GFP("NIST-P192", ECCurve_NIST_P192); |
687 ECTEST_NAMED_GFP("SECP-160K1", ECCurve_SECG_PRIME_160K1); | 641 ECTEST_NAMED_GFP("NIST-P224", ECCurve_NIST_P224); |
688 ECTEST_NAMED_GFP("NIST-P192", ECCurve_NIST_P192); | 642 ECTEST_NAMED_GFP("NIST-P256", ECCurve_NIST_P256); |
689 ECTEST_NAMED_GFP("NIST-P224", ECCurve_NIST_P224); | 643 ECTEST_NAMED_GFP("NIST-P384", ECCurve_NIST_P384); |
690 ECTEST_NAMED_GFP("NIST-P256", ECCurve_NIST_P256); | 644 ECTEST_NAMED_GFP("NIST-P521", ECCurve_NIST_P521); |
691 ECTEST_NAMED_GFP("NIST-P384", ECCurve_NIST_P384); | 645 } |
692 ECTEST_NAMED_GFP("NIST-P521", ECCurve_NIST_P521); | 646 if (ansi) { |
693 } | 647 ECTEST_NAMED_GFP("ANSI X9.62 PRIME192v1", ECCurve_X9_62_PRIME_192V1); |
694 if (ansi) { | 648 ECTEST_NAMED_GFP("ANSI X9.62 PRIME192v2", ECCurve_X9_62_PRIME_192V2); |
695 ECTEST_NAMED_GFP("ANSI X9.62 PRIME192v1", ECCurve_X9_62_PRIME_192V1); | 649 ECTEST_NAMED_GFP("ANSI X9.62 PRIME192v3", ECCurve_X9_62_PRIME_192V3); |
696 ECTEST_NAMED_GFP("ANSI X9.62 PRIME192v2", ECCurve_X9_62_PRIME_192V2); | 650 ECTEST_NAMED_GFP("ANSI X9.62 PRIME239v1", ECCurve_X9_62_PRIME_239V1); |
697 ECTEST_NAMED_GFP("ANSI X9.62 PRIME192v3", ECCurve_X9_62_PRIME_192V3); | 651 ECTEST_NAMED_GFP("ANSI X9.62 PRIME239v2", ECCurve_X9_62_PRIME_239V2); |
698 ECTEST_NAMED_GFP("ANSI X9.62 PRIME239v1", ECCurve_X9_62_PRIME_239V1); | 652 ECTEST_NAMED_GFP("ANSI X9.62 PRIME239v3", ECCurve_X9_62_PRIME_239V3); |
699 ECTEST_NAMED_GFP("ANSI X9.62 PRIME239v2", ECCurve_X9_62_PRIME_239V2); | 653 ECTEST_NAMED_GFP("ANSI X9.62 PRIME256v1", ECCurve_X9_62_PRIME_256V1); |
700 ECTEST_NAMED_GFP("ANSI X9.62 PRIME239v3", ECCurve_X9_62_PRIME_239V3); | 654 } |
701 ECTEST_NAMED_GFP("ANSI X9.62 PRIME256v1", ECCurve_X9_62_PRIME_256V1); | 655 if (secp) { |
702 } | 656 ECTEST_NAMED_GFP("SECP-112R1", ECCurve_SECG_PRIME_112R1); |
703 if (secp) { | 657 ECTEST_NAMED_GFP("SECP-112R2", ECCurve_SECG_PRIME_112R2); |
704 ECTEST_NAMED_GFP("SECP-112R1", ECCurve_SECG_PRIME_112R1); | 658 ECTEST_NAMED_GFP("SECP-128R1", ECCurve_SECG_PRIME_128R1); |
705 ECTEST_NAMED_GFP("SECP-112R2", ECCurve_SECG_PRIME_112R2); | 659 ECTEST_NAMED_GFP("SECP-128R2", ECCurve_SECG_PRIME_128R2); |
706 ECTEST_NAMED_GFP("SECP-128R1", ECCurve_SECG_PRIME_128R1); | 660 ECTEST_NAMED_GFP("SECP-160K1", ECCurve_SECG_PRIME_160K1); |
707 ECTEST_NAMED_GFP("SECP-128R2", ECCurve_SECG_PRIME_128R2); | 661 ECTEST_NAMED_GFP("SECP-160R1", ECCurve_SECG_PRIME_160R1); |
708 ECTEST_NAMED_GFP("SECP-160K1", ECCurve_SECG_PRIME_160K1); | 662 ECTEST_NAMED_GFP("SECP-160R2", ECCurve_SECG_PRIME_160R2); |
709 ECTEST_NAMED_GFP("SECP-160R1", ECCurve_SECG_PRIME_160R1); | 663 ECTEST_NAMED_GFP("SECP-192K1", ECCurve_SECG_PRIME_192K1); |
710 ECTEST_NAMED_GFP("SECP-160R2", ECCurve_SECG_PRIME_160R2); | 664 ECTEST_NAMED_GFP("SECP-192R1", ECCurve_SECG_PRIME_192R1); |
711 ECTEST_NAMED_GFP("SECP-192K1", ECCurve_SECG_PRIME_192K1); | 665 ECTEST_NAMED_GFP("SECP-224K1", ECCurve_SECG_PRIME_224K1); |
712 ECTEST_NAMED_GFP("SECP-192R1", ECCurve_SECG_PRIME_192R1); | 666 ECTEST_NAMED_GFP("SECP-224R1", ECCurve_SECG_PRIME_224R1); |
713 ECTEST_NAMED_GFP("SECP-224K1", ECCurve_SECG_PRIME_224K1); | 667 ECTEST_NAMED_GFP("SECP-256K1", ECCurve_SECG_PRIME_256K1); |
714 ECTEST_NAMED_GFP("SECP-224R1", ECCurve_SECG_PRIME_224R1); | 668 ECTEST_NAMED_GFP("SECP-256R1", ECCurve_SECG_PRIME_256R1); |
715 ECTEST_NAMED_GFP("SECP-256K1", ECCurve_SECG_PRIME_256K1); | 669 ECTEST_NAMED_GFP("SECP-384R1", ECCurve_SECG_PRIME_384R1); |
716 ECTEST_NAMED_GFP("SECP-256R1", ECCurve_SECG_PRIME_256R1); | 670 ECTEST_NAMED_GFP("SECP-521R1", ECCurve_SECG_PRIME_521R1); |
717 ECTEST_NAMED_GFP("SECP-384R1", ECCurve_SECG_PRIME_384R1); | 671 } |
718 ECTEST_NAMED_GFP("SECP-521R1", ECCurve_SECG_PRIME_521R1); | 672 |
719 } | 673 cleanup: |
720 | 674 if (rv != SECSuccess) { |
721 cleanup: | 675 printf("Error: exiting with error value\n"); |
722 if (rv != SECSuccess) { | 676 } |
723 » printf("Error: exiting with error value\n"); | 677 return rv; |
724 } | 678 } |
725 return rv; | |
726 } | |
OLD | NEW |