/src/nss/lib/softoken/fipstokn.c
Line | Count | Source |
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 |
3 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
4 | | /* |
5 | | * This file implements PKCS 11 on top of our existing security modules |
6 | | * |
7 | | * For more information about PKCS 11 See PKCS 11 Token Inteface Standard. |
8 | | * This implementation has two slots: |
9 | | * slot 1 is our generic crypto support. It does not require login |
10 | | * (unless you've enabled FIPS). It supports Public Key ops, and all they |
11 | | * bulk ciphers and hashes. It can also support Private Key ops for imported |
12 | | * Private keys. It does not have any token storage. |
13 | | * slot 2 is our private key support. It requires a login before use. It |
14 | | * can store Private Keys and Certs as token objects. Currently only private |
15 | | * keys and their associated Certificates are saved on the token. |
16 | | * |
17 | | * In this implementation, session objects are only visible to the session |
18 | | * that created or generated them. |
19 | | */ |
20 | | #include "seccomon.h" |
21 | | #include "softoken.h" |
22 | | #include "lowkeyi.h" |
23 | | #include "pkcs11.h" |
24 | | #include "pkcs11i.h" |
25 | | #include "prenv.h" |
26 | | #include "prprf.h" |
27 | | |
28 | | #include <ctype.h> |
29 | | |
30 | | #ifdef XP_UNIX |
31 | | #define NSS_AUDIT_WITH_SYSLOG 1 |
32 | | #include <syslog.h> |
33 | | #include <unistd.h> |
34 | | #endif |
35 | | |
36 | | #ifdef LINUX |
37 | | #include <pthread.h> |
38 | | #include <dlfcn.h> |
39 | 0 | #define LIBAUDIT_NAME "libaudit.so.1" |
40 | | #ifndef AUDIT_CRYPTO_TEST_USER |
41 | 0 | #define AUDIT_CRYPTO_TEST_USER 2400 /* Crypto test results */ |
42 | 0 | #define AUDIT_CRYPTO_PARAM_CHANGE_USER 2401 /* Crypto attribute change */ |
43 | 0 | #define AUDIT_CRYPTO_LOGIN 2402 /* Logged in as crypto officer */ |
44 | 0 | #define AUDIT_CRYPTO_LOGOUT 2403 /* Logged out from crypto */ |
45 | 0 | #define AUDIT_CRYPTO_KEY_USER 2404 /* Create,delete,negotiate */ |
46 | 0 | #define AUDIT_CRYPTO_FAILURE_USER 2405 /* Fail decrypt,encrypt,randomize */ |
47 | | #endif |
48 | | static void *libaudit_handle; |
49 | | static int (*audit_open_func)(void); |
50 | | static void (*audit_close_func)(int fd); |
51 | | static int (*audit_log_user_message_func)(int audit_fd, int type, |
52 | | const char *message, const char *hostname, const char *addr, |
53 | | const char *tty, int result); |
54 | | static int (*audit_send_user_message_func)(int fd, int type, |
55 | | const char *message); |
56 | | |
57 | | static pthread_once_t libaudit_once_control = PTHREAD_ONCE_INIT; |
58 | | |
59 | | static void |
60 | | libaudit_init(void) |
61 | 0 | { |
62 | 0 | libaudit_handle = dlopen(LIBAUDIT_NAME, RTLD_LAZY); |
63 | 0 | if (!libaudit_handle) { |
64 | 0 | return; |
65 | 0 | } |
66 | 0 | audit_open_func = dlsym(libaudit_handle, "audit_open"); |
67 | 0 | audit_close_func = dlsym(libaudit_handle, "audit_close"); |
68 | | /* |
69 | | * audit_send_user_message is the older function. |
70 | | * audit_log_user_message, if available, is preferred. |
71 | | */ |
72 | 0 | audit_log_user_message_func = dlsym(libaudit_handle, |
73 | 0 | "audit_log_user_message"); |
74 | 0 | if (!audit_log_user_message_func) { |
75 | 0 | audit_send_user_message_func = dlsym(libaudit_handle, |
76 | 0 | "audit_send_user_message"); |
77 | 0 | } |
78 | 0 | if (!audit_open_func || !audit_close_func || |
79 | 0 | (!audit_log_user_message_func && !audit_send_user_message_func)) { |
80 | 0 | dlclose(libaudit_handle); |
81 | 0 | libaudit_handle = NULL; |
82 | 0 | audit_open_func = NULL; |
83 | 0 | audit_close_func = NULL; |
84 | 0 | audit_log_user_message_func = NULL; |
85 | 0 | audit_send_user_message_func = NULL; |
86 | 0 | } |
87 | 0 | } |
88 | | #endif /* LINUX */ |
89 | | |
90 | | /* |
91 | | * ******************** Password Utilities ******************************* |
92 | | */ |
93 | | static PRBool isLoggedIn = PR_FALSE; |
94 | | static PRBool isLevel2 = PR_TRUE; |
95 | | PRBool sftk_fatalError = PR_FALSE; |
96 | | |
97 | | /* |
98 | | * This function returns |
99 | | * - CKR_PIN_INVALID if the password/PIN is not a legal UTF8 string |
100 | | * - CKR_PIN_LEN_RANGE if the password/PIN is too short or does not |
101 | | * consist of characters from three or more character classes. |
102 | | * - CKR_OK otherwise |
103 | | * |
104 | | * The minimum password/PIN length is FIPS_MIN_PIN Unicode characters. |
105 | | * We define five character classes: digits (0-9), ASCII lowercase letters, |
106 | | * ASCII uppercase letters, ASCII non-alphanumeric characters (such as |
107 | | * space and punctuation marks), and non-ASCII characters. If an ASCII |
108 | | * uppercase letter is the first character of the password/PIN, the |
109 | | * uppercase letter is not counted toward its character class. Similarly, |
110 | | * if a digit is the last character of the password/PIN, the digit is not |
111 | | * counted toward its character class. |
112 | | * |
113 | | * Although NSC_SetPIN and NSC_InitPIN already do the maximum and minimum |
114 | | * password/PIN length checks, they check the length in bytes as opposed |
115 | | * to characters. To meet the minimum password/PIN guessing probability |
116 | | * requirements in FIPS 140-2, we need to check the length in characters. |
117 | | */ |
118 | | static CK_RV |
119 | | sftk_newPinCheck(CK_CHAR_PTR pPin, CK_ULONG ulPinLen) |
120 | 0 | { |
121 | 0 | unsigned int i; |
122 | 0 | int nchar = 0; /* number of characters */ |
123 | 0 | int ntrail = 0; /* number of trailing bytes to follow */ |
124 | 0 | int ndigit = 0; /* number of decimal digits */ |
125 | 0 | int nlower = 0; /* number of ASCII lowercase letters */ |
126 | 0 | int nupper = 0; /* number of ASCII uppercase letters */ |
127 | 0 | int nnonalnum = 0; /* number of ASCII non-alphanumeric characters */ |
128 | 0 | int nnonascii = 0; /* number of non-ASCII characters */ |
129 | 0 | int nclass; /* number of character classes */ |
130 | |
|
131 | 0 | for (i = 0; i < ulPinLen; i++) { |
132 | 0 | unsigned int byte = pPin[i]; |
133 | |
|
134 | 0 | if (ntrail) { |
135 | 0 | if ((byte & 0xc0) != 0x80) { |
136 | | /* illegal */ |
137 | 0 | nchar = -1; |
138 | 0 | break; |
139 | 0 | } |
140 | 0 | if (--ntrail == 0) { |
141 | 0 | nchar++; |
142 | 0 | nnonascii++; |
143 | 0 | } |
144 | 0 | continue; |
145 | 0 | } |
146 | 0 | if ((byte & 0x80) == 0x00) { |
147 | | /* single-byte (ASCII) character */ |
148 | 0 | nchar++; |
149 | 0 | if (isdigit(byte)) { |
150 | 0 | if (i < ulPinLen - 1) { |
151 | 0 | ndigit++; |
152 | 0 | } |
153 | 0 | } else if (islower(byte)) { |
154 | 0 | nlower++; |
155 | 0 | } else if (isupper(byte)) { |
156 | 0 | if (i > 0) { |
157 | 0 | nupper++; |
158 | 0 | } |
159 | 0 | } else { |
160 | 0 | nnonalnum++; |
161 | 0 | } |
162 | 0 | } else if ((byte & 0xe0) == 0xc0) { |
163 | | /* leading byte of two-byte character */ |
164 | 0 | ntrail = 1; |
165 | 0 | } else if ((byte & 0xf0) == 0xe0) { |
166 | | /* leading byte of three-byte character */ |
167 | 0 | ntrail = 2; |
168 | 0 | } else if ((byte & 0xf8) == 0xf0) { |
169 | | /* leading byte of four-byte character */ |
170 | 0 | ntrail = 3; |
171 | 0 | } else { |
172 | | /* illegal */ |
173 | 0 | nchar = -1; |
174 | 0 | break; |
175 | 0 | } |
176 | 0 | } |
177 | 0 | if (nchar == -1) { |
178 | | /* illegal UTF8 string */ |
179 | 0 | return CKR_PIN_INVALID; |
180 | 0 | } |
181 | 0 | if (nchar < FIPS_MIN_PIN) { |
182 | 0 | return CKR_PIN_LEN_RANGE; |
183 | 0 | } |
184 | 0 | nclass = (ndigit != 0) + (nlower != 0) + (nupper != 0) + |
185 | 0 | (nnonalnum != 0) + (nnonascii != 0); |
186 | 0 | if (nclass < 3) { |
187 | 0 | return CKR_PIN_LEN_RANGE; |
188 | 0 | } |
189 | 0 | return CKR_OK; |
190 | 0 | } |
191 | | |
192 | | /* FIPS required checks before any useful cryptographic services */ |
193 | | static CK_RV |
194 | | sftk_fipsCheck(void) |
195 | 0 | { |
196 | 0 | if (sftk_fatalError) |
197 | 0 | return CKR_DEVICE_ERROR; |
198 | 0 | if (isLevel2 && !isLoggedIn) |
199 | 0 | return CKR_USER_NOT_LOGGED_IN; |
200 | 0 | return CKR_OK; |
201 | 0 | } |
202 | | |
203 | | #define SFTK_FIPSCHECK() \ |
204 | 0 | CK_RV rv; \ |
205 | 0 | if ((rv = sftk_fipsCheck()) != CKR_OK) \ |
206 | 0 | return rv; |
207 | | |
208 | | #define SFTK_FIPSFATALCHECK() \ |
209 | 0 | if (sftk_fatalError) \ |
210 | 0 | return CKR_DEVICE_ERROR; |
211 | | |
212 | | /* grab an attribute out of a raw template */ |
213 | | void * |
214 | | fc_getAttribute(CK_ATTRIBUTE_PTR pTemplate, |
215 | | CK_ULONG ulCount, CK_ATTRIBUTE_TYPE type) |
216 | 0 | { |
217 | 0 | int i; |
218 | |
|
219 | 0 | for (i = 0; i < (int)ulCount; i++) { |
220 | 0 | if (pTemplate[i].type == type) { |
221 | 0 | return pTemplate[i].pValue; |
222 | 0 | } |
223 | 0 | } |
224 | 0 | return NULL; |
225 | 0 | } |
226 | | |
227 | | #define __PASTE(x, y) x##y |
228 | | |
229 | | /* ------------- forward declare all the NSC_ functions ------------- */ |
230 | | #undef CK_NEED_ARG_LIST |
231 | | #undef CK_PKCS11_FUNCTION_INFO |
232 | | |
233 | | #define CK_PKCS11_3_2 1 |
234 | | #define CK_PKCS11_3_0 1 |
235 | | |
236 | | #define CK_PKCS11_FUNCTION_INFO(name) CK_RV __PASTE(NS, name) |
237 | | #define CK_NEED_ARG_LIST 1 |
238 | | |
239 | | #include "pkcs11f.h" |
240 | | |
241 | | /* ------------- forward declare all the FIPS functions ------------- */ |
242 | | #undef CK_NEED_ARG_LIST |
243 | | #undef CK_PKCS11_FUNCTION_INFO |
244 | | |
245 | | #define CK_PKCS11_FUNCTION_INFO(name) CK_RV __PASTE(F, name) |
246 | | #define CK_NEED_ARG_LIST 1 |
247 | | |
248 | | #include "pkcs11f.h" |
249 | | |
250 | | /* ------------- build the CK_CRYPTO_TABLE ------------------------- */ |
251 | | static CK_FUNCTION_LIST_3_2 sftk_fipsTable_v32 = { |
252 | | { 3, 2 }, |
253 | | |
254 | | #undef CK_NEED_ARG_LIST |
255 | | #undef CK_PKCS11_FUNCTION_INFO |
256 | | |
257 | | #define CK_PKCS11_3_2_ONLY 1 |
258 | | #define CK_PKCS11_FUNCTION_INFO(name) \ |
259 | | __PASTE(F, name) \ |
260 | | , |
261 | | |
262 | | #include "pkcs11f.h" |
263 | | |
264 | | }; |
265 | | #undef CK_PKCS11_3_2_ONLY |
266 | | |
267 | | static CK_FUNCTION_LIST_3_0 sftk_fipsTable_v30 = { |
268 | | { 3, 0 }, |
269 | | |
270 | | #undef CK_NEED_ARG_LIST |
271 | | #undef CK_PKCS11_FUNCTION_INFO |
272 | | |
273 | | #define CK_PKCS11_3_0_ONLY 1 |
274 | | #define CK_PKCS11_FUNCTION_INFO(name) \ |
275 | | __PASTE(F, name) \ |
276 | | , |
277 | | |
278 | | #include "pkcs11f.h" |
279 | | |
280 | | }; |
281 | | #undef CK_PKCS11_3_0_ONLY |
282 | | |
283 | | /* forward declaration of special GetInfo functions */ |
284 | | CK_RV FC_GetInfoV2(CK_INFO_PTR pInfo); |
285 | | CK_RV NSC_GetInfoV2(CK_INFO_PTR pInfo); |
286 | | CK_RV FC_GetMechanismInfoV2(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, |
287 | | CK_MECHANISM_INFO_PTR pInfo); |
288 | | CK_RV NSC_GetMechanismInfoV2(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, |
289 | | CK_MECHANISM_INFO_PTR pInfo); |
290 | | |
291 | | static CK_FUNCTION_LIST sftk_fipsTable_v2 = { |
292 | | { 2, 40 }, |
293 | | |
294 | | #undef CK_PKCS11_3_0 |
295 | | #define CK_PKCS11_2_0_ONLY 1 |
296 | | #undef CK_NEED_ARG_LIST |
297 | | #undef CK_PKCS11_FUNCTION_INFO |
298 | | #define C_GetInfo C_GetInfoV2 |
299 | | #define C_GetMechanismInfo C_GetMechanismInfoV2 |
300 | | |
301 | | #define CK_PKCS11_FUNCTION_INFO(name) \ |
302 | | __PASTE(F, name) \ |
303 | | , |
304 | | |
305 | | #include "pkcs11f.h" |
306 | | |
307 | | }; |
308 | | |
309 | | #undef C_GetInfo |
310 | | #undef C_GetMechanismInfo |
311 | | #undef CK_NEED_ARG_LIST |
312 | | #undef CK_PKCS11_FUNCTION_INFO |
313 | | #undef CK_PKCS11_2_0_ONLY |
314 | | |
315 | | #undef __PASTE |
316 | | |
317 | | /* |
318 | | * Array is orderd by default first |
319 | | */ |
320 | | static CK_INTERFACE fips_interfaces[] = { |
321 | | { (CK_UTF8CHAR_PTR) "PKCS 11", &sftk_fipsTable_v32, NSS_INTERFACE_FLAGS }, |
322 | | { (CK_UTF8CHAR_PTR) "PKCS 11", &sftk_fipsTable_v30, NSS_INTERFACE_FLAGS }, |
323 | | { (CK_UTF8CHAR_PTR) "PKCS 11", &sftk_fipsTable_v2, NSS_INTERFACE_FLAGS }, |
324 | | { (CK_UTF8CHAR_PTR) "Vendor NSS Module Interface", &sftk_module_funcList, NSS_INTERFACE_FLAGS }, |
325 | | { (CK_UTF8CHAR_PTR) "Vendor NSS FIPS Interface", &sftk_fips_funcList, NSS_INTERFACE_FLAGS } |
326 | | }; |
327 | | /* must match the count of interfaces in fips_interfaces above*/ |
328 | 0 | #define FIPS_INTERFACE_COUNT PR_ARRAY_SIZE(fips_interfaces) |
329 | | |
330 | | /* CKO_NOT_A_KEY can be any object class that's not a key object. */ |
331 | 0 | #define CKO_NOT_A_KEY CKO_DATA |
332 | | |
333 | | #define SFTK_IS_KEY_OBJECT(objClass) \ |
334 | 0 | (((objClass) == CKO_PUBLIC_KEY) || \ |
335 | 0 | ((objClass) == CKO_PRIVATE_KEY) || \ |
336 | 0 | ((objClass) == CKO_SECRET_KEY)) |
337 | | |
338 | | #define SFTK_IS_NONPUBLIC_KEY_OBJECT(objClass) \ |
339 | 0 | (((objClass) == CKO_PRIVATE_KEY) || ((objClass) == CKO_SECRET_KEY)) |
340 | | |
341 | | static CK_RV |
342 | | sftk_get_object_class_and_fipsCheck(CK_SESSION_HANDLE hSession, |
343 | | CK_OBJECT_HANDLE hObject, CK_OBJECT_CLASS *pObjClass) |
344 | 0 | { |
345 | 0 | CK_RV rv; |
346 | 0 | CK_ATTRIBUTE class; |
347 | 0 | class.type = CKA_CLASS; |
348 | 0 | class.pValue = pObjClass; |
349 | 0 | class.ulValueLen = sizeof(*pObjClass); |
350 | 0 | rv = NSC_GetAttributeValue(hSession, hObject, &class, 1); |
351 | 0 | if ((rv == CKR_OK) && SFTK_IS_NONPUBLIC_KEY_OBJECT(*pObjClass)) { |
352 | 0 | rv = sftk_fipsCheck(); |
353 | 0 | } |
354 | 0 | return rv; |
355 | 0 | } |
356 | | |
357 | | #ifdef LINUX |
358 | | |
359 | | int |
360 | | sftk_mapLinuxAuditType(NSSAuditSeverity severity, NSSAuditType auditType) |
361 | 0 | { |
362 | 0 | switch (auditType) { |
363 | 0 | case NSS_AUDIT_ACCESS_KEY: |
364 | 0 | case NSS_AUDIT_CHANGE_KEY: |
365 | 0 | case NSS_AUDIT_COPY_KEY: |
366 | 0 | case NSS_AUDIT_DERIVE_KEY: |
367 | 0 | case NSS_AUDIT_DESTROY_KEY: |
368 | 0 | case NSS_AUDIT_DIGEST_KEY: |
369 | 0 | case NSS_AUDIT_GENERATE_KEY: |
370 | 0 | case NSS_AUDIT_LOAD_KEY: |
371 | 0 | case NSS_AUDIT_UNWRAP_KEY: |
372 | 0 | case NSS_AUDIT_WRAP_KEY: |
373 | 0 | case NSS_AUDIT_ENCAPSULATE_KEY: |
374 | 0 | case NSS_AUDIT_DECAPSULATE_KEY: |
375 | 0 | return AUDIT_CRYPTO_KEY_USER; |
376 | 0 | case NSS_AUDIT_CRYPT: |
377 | 0 | return (severity == NSS_AUDIT_ERROR) ? AUDIT_CRYPTO_FAILURE_USER : AUDIT_CRYPTO_KEY_USER; |
378 | 0 | case NSS_AUDIT_FIPS_STATE: |
379 | 0 | case NSS_AUDIT_INIT_PIN: |
380 | 0 | case NSS_AUDIT_INIT_TOKEN: |
381 | 0 | case NSS_AUDIT_SET_PIN: |
382 | 0 | return AUDIT_CRYPTO_PARAM_CHANGE_USER; |
383 | 0 | case NSS_AUDIT_SELF_TEST: |
384 | 0 | return AUDIT_CRYPTO_TEST_USER; |
385 | 0 | case NSS_AUDIT_LOGIN: |
386 | 0 | return AUDIT_CRYPTO_LOGIN; |
387 | 0 | case NSS_AUDIT_LOGOUT: |
388 | 0 | return AUDIT_CRYPTO_LOGOUT; |
389 | | /* we skip the fault case here so we can get compiler |
390 | | * warnings if new 'NSSAuditType's are added without |
391 | | * added them to this list, defaults fall through */ |
392 | 0 | } |
393 | | /* default */ |
394 | 0 | return AUDIT_CRYPTO_PARAM_CHANGE_USER; |
395 | 0 | } |
396 | | #endif |
397 | | |
398 | | /********************************************************************** |
399 | | * |
400 | | * FIPS 140 auditable event logging |
401 | | * |
402 | | **********************************************************************/ |
403 | | |
404 | | PRBool sftk_audit_enabled = PR_FALSE; |
405 | | |
406 | | /* |
407 | | * Each audit record must have the following information: |
408 | | * - Date and time of the event |
409 | | * - Type of event |
410 | | * - user (subject) identity |
411 | | * - outcome (success or failure) of the event |
412 | | * - process ID |
413 | | * - name (ID) of the object |
414 | | * - for changes to data (except for authentication data and CSPs), the new |
415 | | * and old values of the data |
416 | | * - for authentication attempts, the origin of the attempt (e.g., terminal |
417 | | * identifier) |
418 | | * - for assuming a role, the type of role, and the location of the request |
419 | | */ |
420 | | void |
421 | | sftk_LogAuditMessage(NSSAuditSeverity severity, NSSAuditType auditType, |
422 | | const char *msg) |
423 | 0 | { |
424 | 0 | #ifdef NSS_AUDIT_WITH_SYSLOG |
425 | 0 | int level; |
426 | |
|
427 | 0 | switch (severity) { |
428 | 0 | case NSS_AUDIT_ERROR: |
429 | 0 | level = LOG_ERR; |
430 | 0 | break; |
431 | 0 | case NSS_AUDIT_WARNING: |
432 | 0 | level = LOG_WARNING; |
433 | 0 | break; |
434 | 0 | default: |
435 | 0 | level = LOG_INFO; |
436 | 0 | break; |
437 | 0 | } |
438 | | /* timestamp is provided by syslog in the message header */ |
439 | 0 | syslog(level | LOG_USER /* facility */, |
440 | 0 | "NSS " SOFTOKEN_LIB_NAME "[pid=%d uid=%d]: %s", |
441 | 0 | (int)getpid(), (int)getuid(), msg); |
442 | 0 | #ifdef LINUX |
443 | 0 | if (pthread_once(&libaudit_once_control, libaudit_init) != 0) { |
444 | 0 | return; |
445 | 0 | } |
446 | 0 | if (libaudit_handle) { |
447 | 0 | int audit_fd; |
448 | 0 | int linuxAuditType; |
449 | 0 | int result = (severity != NSS_AUDIT_ERROR); /* 1=success; 0=failed */ |
450 | 0 | char *message = PR_smprintf("NSS " SOFTOKEN_LIB_NAME ": %s", msg); |
451 | 0 | if (!message) { |
452 | 0 | return; |
453 | 0 | } |
454 | 0 | audit_fd = audit_open_func(); |
455 | 0 | if (audit_fd < 0) { |
456 | 0 | PR_smprintf_free(message); |
457 | 0 | return; |
458 | 0 | } |
459 | 0 | linuxAuditType = sftk_mapLinuxAuditType(severity, auditType); |
460 | 0 | if (audit_log_user_message_func) { |
461 | 0 | audit_log_user_message_func(audit_fd, linuxAuditType, message, |
462 | 0 | NULL, NULL, NULL, result); |
463 | 0 | } else { |
464 | 0 | audit_send_user_message_func(audit_fd, linuxAuditType, message); |
465 | 0 | } |
466 | 0 | audit_close_func(audit_fd); |
467 | 0 | PR_smprintf_free(message); |
468 | 0 | } |
469 | 0 | #endif /* LINUX */ |
470 | | #else |
471 | | /* do nothing */ |
472 | | #endif |
473 | 0 | } |
474 | | |
475 | | /********************************************************************** |
476 | | * |
477 | | * Start of PKCS 11 functions |
478 | | * |
479 | | **********************************************************************/ |
480 | | /* return the function list */ |
481 | | CK_RV |
482 | | FC_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList) |
483 | 0 | { |
484 | |
|
485 | 0 | CHECK_FORK(); |
486 | |
|
487 | 0 | *pFunctionList = &sftk_fipsTable_v2; |
488 | 0 | return CKR_OK; |
489 | 0 | } |
490 | | |
491 | | CK_RV |
492 | | FC_GetInterfaceList(CK_INTERFACE_PTR interfaces, CK_ULONG_PTR pulCount) |
493 | 0 | { |
494 | 0 | CK_ULONG count = *pulCount; |
495 | 0 | *pulCount = FIPS_INTERFACE_COUNT; |
496 | 0 | if (interfaces == NULL) { |
497 | 0 | return CKR_OK; |
498 | 0 | } |
499 | 0 | if (count < FIPS_INTERFACE_COUNT) { |
500 | 0 | return CKR_BUFFER_TOO_SMALL; |
501 | 0 | } |
502 | 0 | PORT_Memcpy(interfaces, fips_interfaces, sizeof(fips_interfaces)); |
503 | 0 | return CKR_OK; |
504 | 0 | } |
505 | | |
506 | | /* |
507 | | * Get the requested interface, use the fips_interfaces array so we can |
508 | | * easily add new interfaces as they occur. |
509 | | */ |
510 | | CK_RV |
511 | | FC_GetInterface(CK_UTF8CHAR_PTR pInterfaceName, CK_VERSION_PTR pVersion, |
512 | | CK_INTERFACE_PTR_PTR ppInterface, CK_FLAGS flags) |
513 | 0 | { |
514 | 0 | int i; |
515 | 0 | for (i = 0; i < FIPS_INTERFACE_COUNT; i++) { |
516 | 0 | CK_INTERFACE_PTR interface = &fips_interfaces[i]; |
517 | 0 | if (pInterfaceName && PORT_Strcmp((char *)pInterfaceName, (char *)interface->pInterfaceName) != 0) { |
518 | 0 | continue; |
519 | 0 | } |
520 | 0 | if (pVersion && PORT_Memcmp(pVersion, (CK_VERSION *)interface->pFunctionList, sizeof(CK_VERSION)) != 0) { |
521 | 0 | continue; |
522 | 0 | } |
523 | 0 | if (flags & ((interface->flags & flags) != flags)) { |
524 | 0 | continue; |
525 | 0 | } |
526 | 0 | *ppInterface = interface; |
527 | 0 | return CKR_OK; |
528 | 0 | } |
529 | 0 | return CKR_ARGUMENTS_BAD; |
530 | 0 | } |
531 | | |
532 | | /* sigh global so pkcs11 can read it */ |
533 | | PRBool nsf_init = PR_FALSE; |
534 | | |
535 | | void |
536 | | fc_log_init_error(CK_RV crv) |
537 | 0 | { |
538 | 0 | if (sftk_audit_enabled) { |
539 | 0 | char msg[128]; |
540 | 0 | PR_snprintf(msg, sizeof msg, |
541 | 0 | "C_Initialize()=0x%08lX " |
542 | 0 | "power-up self-tests failed", |
543 | 0 | (PRUint32)crv); |
544 | 0 | sftk_LogAuditMessage(NSS_AUDIT_ERROR, NSS_AUDIT_SELF_TEST, msg); |
545 | 0 | } |
546 | 0 | } |
547 | | |
548 | | /* FC_Initialize initializes the PKCS #11 library. */ |
549 | | CK_RV |
550 | | FC_Initialize(CK_VOID_PTR pReserved) |
551 | 0 | { |
552 | 0 | const char *envp; |
553 | 0 | CK_RV crv; |
554 | 0 | PRBool rerun; |
555 | |
|
556 | 0 | if ((envp = PR_GetEnv("NSS_ENABLE_AUDIT")) != NULL) { |
557 | 0 | sftk_audit_enabled = (atoi(envp) == 1); |
558 | 0 | } |
559 | | |
560 | | /* if we have the forcePOST flag on, rerun the integrity checks */ |
561 | | /* we need to know this before we fully parse the arguments in |
562 | | * nsc_CommonInitialize, so read it now */ |
563 | 0 | rerun = sftk_RawArgHasFlag("flags", "forcePost", pReserved); |
564 | | |
565 | | /* At this point we should have already done post and integrity checks. |
566 | | * if we haven't, it probably means the FIPS product has not been installed |
567 | | * or the tests failed. Don't let an application try to enter FIPS mode. This |
568 | | * also forces the tests to be rerun if forcePOST is set. */ |
569 | 0 | crv = sftk_FIPSEntryOK(rerun); |
570 | 0 | if (crv != CKR_OK) { |
571 | 0 | sftk_fatalError = PR_TRUE; |
572 | 0 | fc_log_init_error(crv); |
573 | 0 | return crv; |
574 | 0 | } |
575 | | |
576 | 0 | sftk_ForkReset(pReserved, &crv); |
577 | |
|
578 | 0 | if (nsf_init) { |
579 | 0 | return CKR_CRYPTOKI_ALREADY_INITIALIZED; |
580 | 0 | } |
581 | | |
582 | 0 | crv = nsc_CommonInitialize(pReserved, PR_TRUE); |
583 | | |
584 | | /* not an 'else' rv can be set by either SFTK_LowInit or SFTK_SlotInit*/ |
585 | 0 | if (crv != CKR_OK) { |
586 | 0 | sftk_fatalError = PR_TRUE; |
587 | 0 | return crv; |
588 | 0 | } |
589 | | |
590 | 0 | sftk_fatalError = PR_FALSE; /* any error has been reset */ |
591 | 0 | nsf_init = PR_TRUE; |
592 | 0 | isLevel2 = PR_TRUE; /* assume level 2 unless we learn otherwise */ |
593 | |
|
594 | 0 | return CKR_OK; |
595 | 0 | } |
596 | | |
597 | | /*FC_Finalize indicates that an application is done with the PKCS #11 library.*/ |
598 | | CK_RV |
599 | | FC_Finalize(CK_VOID_PTR pReserved) |
600 | 0 | { |
601 | 0 | CK_RV crv; |
602 | |
|
603 | 0 | if (sftk_ForkReset(pReserved, &crv)) { |
604 | 0 | return crv; |
605 | 0 | } |
606 | | |
607 | 0 | if (!nsf_init) { |
608 | 0 | return CKR_OK; |
609 | 0 | } |
610 | | |
611 | 0 | crv = nsc_CommonFinalize(pReserved, PR_TRUE); |
612 | |
|
613 | 0 | nsf_init = (PRBool) !(crv == CKR_OK); |
614 | 0 | return crv; |
615 | 0 | } |
616 | | |
617 | | /* FC_GetInfo returns general information about PKCS #11. */ |
618 | | CK_RV |
619 | | FC_GetInfo(CK_INFO_PTR pInfo) |
620 | 0 | { |
621 | 0 | CHECK_FORK(); |
622 | |
|
623 | 0 | return NSC_GetInfo(pInfo); |
624 | 0 | } |
625 | | |
626 | | /* FC_GetInfo returns general information about PKCS #11. */ |
627 | | CK_RV |
628 | | FC_GetInfoV2(CK_INFO_PTR pInfo) |
629 | 0 | { |
630 | 0 | CHECK_FORK(); |
631 | |
|
632 | 0 | return NSC_GetInfoV2(pInfo); |
633 | 0 | } |
634 | | |
635 | | /* FC_GetSlotList obtains a list of slots in the system. */ |
636 | | CK_RV |
637 | | FC_GetSlotList(CK_BBOOL tokenPresent, |
638 | | CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount) |
639 | 0 | { |
640 | 0 | CHECK_FORK(); |
641 | |
|
642 | 0 | return nsc_CommonGetSlotList(tokenPresent, pSlotList, pulCount, |
643 | 0 | NSC_FIPS_MODULE); |
644 | 0 | } |
645 | | |
646 | | /* FC_GetSlotInfo obtains information about a particular slot in the system. */ |
647 | | CK_RV |
648 | | FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) |
649 | 0 | { |
650 | 0 | CHECK_FORK(); |
651 | |
|
652 | 0 | return NSC_GetSlotInfo(slotID, pInfo); |
653 | 0 | } |
654 | | |
655 | | /*FC_GetTokenInfo obtains information about a particular token in the system.*/ |
656 | | CK_RV |
657 | | FC_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) |
658 | 0 | { |
659 | 0 | CK_RV crv; |
660 | |
|
661 | 0 | CHECK_FORK(); |
662 | |
|
663 | 0 | crv = NSC_GetTokenInfo(slotID, pInfo); |
664 | 0 | if (crv == CKR_OK) { |
665 | | /* use the global database to figure out if we are running in |
666 | | * FIPS 140 Level 1 or Level 2 */ |
667 | 0 | if (slotID == FIPS_SLOT_ID && |
668 | 0 | (pInfo->flags & CKF_LOGIN_REQUIRED) == 0) { |
669 | 0 | isLevel2 = PR_FALSE; |
670 | 0 | } |
671 | 0 | } |
672 | 0 | return crv; |
673 | 0 | } |
674 | | |
675 | | /*FC_GetMechanismList obtains a list of mechanism types supported by a token.*/ |
676 | | CK_RV |
677 | | FC_GetMechanismList(CK_SLOT_ID slotID, |
678 | | CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pusCount) |
679 | 0 | { |
680 | 0 | CHECK_FORK(); |
681 | |
|
682 | 0 | SFTK_FIPSFATALCHECK(); |
683 | 0 | if (sftk_isFIPS(slotID)) { |
684 | 0 | slotID = NETSCAPE_SLOT_ID; |
685 | 0 | } |
686 | | /* FIPS Slots support all functions */ |
687 | 0 | return NSC_GetMechanismList(slotID, pMechanismList, pusCount); |
688 | 0 | } |
689 | | |
690 | | /* FC_GetMechanismInfo obtains information about a particular mechanism |
691 | | * possibly supported by a token. */ |
692 | | CK_RV |
693 | | FC_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, |
694 | | CK_MECHANISM_INFO_PTR pInfo) |
695 | 0 | { |
696 | 0 | CHECK_FORK(); |
697 | |
|
698 | 0 | SFTK_FIPSFATALCHECK(); |
699 | 0 | if (sftk_isFIPS(slotID)) { |
700 | 0 | slotID = NETSCAPE_SLOT_ID; |
701 | 0 | } |
702 | | /* FIPS Slots support all functions */ |
703 | 0 | return NSC_GetMechanismInfo(slotID, type, pInfo); |
704 | 0 | } |
705 | | |
706 | | /* FC_GetMechanismInfoV2 same as FC_GetMechanismInfo except the Message |
707 | | * flags have been stripped out */ |
708 | | CK_RV |
709 | | FC_GetMechanismInfoV2(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, |
710 | | CK_MECHANISM_INFO_PTR pInfo) |
711 | 0 | { |
712 | 0 | CHECK_FORK(); |
713 | |
|
714 | 0 | SFTK_FIPSFATALCHECK(); |
715 | 0 | if (sftk_isFIPS(slotID)) { |
716 | 0 | slotID = NETSCAPE_SLOT_ID; |
717 | 0 | } |
718 | | /* FIPS Slots support all functions */ |
719 | 0 | return NSC_GetMechanismInfoV2(slotID, type, pInfo); |
720 | 0 | } |
721 | | |
722 | | /* FC_InitToken initializes a token. */ |
723 | | CK_RV |
724 | | FC_InitToken(CK_SLOT_ID slotID, CK_CHAR_PTR pPin, |
725 | | CK_ULONG usPinLen, CK_CHAR_PTR pLabel) |
726 | 0 | { |
727 | 0 | CK_RV crv; |
728 | |
|
729 | 0 | CHECK_FORK(); |
730 | |
|
731 | 0 | crv = NSC_InitToken(slotID, pPin, usPinLen, pLabel); |
732 | 0 | if (sftk_audit_enabled) { |
733 | 0 | char msg[128]; |
734 | 0 | NSSAuditSeverity severity = (crv == CKR_OK) ? NSS_AUDIT_INFO : NSS_AUDIT_ERROR; |
735 | | /* pLabel points to a 32-byte label, which is not null-terminated */ |
736 | 0 | PR_snprintf(msg, sizeof msg, |
737 | 0 | "C_InitToken(slotID=%lu, pLabel=\"%.32s\")=0x%08lX", |
738 | 0 | (PRUint32)slotID, pLabel, (PRUint32)crv); |
739 | 0 | sftk_LogAuditMessage(severity, NSS_AUDIT_INIT_TOKEN, msg); |
740 | 0 | } |
741 | 0 | return crv; |
742 | 0 | } |
743 | | |
744 | | /* FC_InitPIN initializes the normal user's PIN. */ |
745 | | CK_RV |
746 | | FC_InitPIN(CK_SESSION_HANDLE hSession, |
747 | | CK_CHAR_PTR pPin, CK_ULONG ulPinLen) |
748 | 0 | { |
749 | 0 | CK_RV rv; |
750 | |
|
751 | 0 | CHECK_FORK(); |
752 | |
|
753 | 0 | if (sftk_fatalError) |
754 | 0 | return CKR_DEVICE_ERROR; |
755 | | /* NSC_InitPIN will only work once per database. We can either initialize |
756 | | * it to level1 (pin len == 0) or level2. If we initialize to level 2, then |
757 | | * we need to make sure the pin meets FIPS requirements */ |
758 | 0 | if ((ulPinLen == 0) || ((rv = sftk_newPinCheck(pPin, ulPinLen)) == CKR_OK)) { |
759 | 0 | rv = NSC_InitPIN(hSession, pPin, ulPinLen); |
760 | 0 | if ((rv == CKR_OK) && |
761 | 0 | (sftk_SlotIDFromSessionHandle(hSession) == FIPS_SLOT_ID)) { |
762 | 0 | isLevel2 = (ulPinLen > 0) ? PR_TRUE : PR_FALSE; |
763 | 0 | } |
764 | 0 | } |
765 | 0 | if (sftk_audit_enabled) { |
766 | 0 | char msg[128]; |
767 | 0 | NSSAuditSeverity severity = (rv == CKR_OK) ? NSS_AUDIT_INFO : NSS_AUDIT_ERROR; |
768 | 0 | PR_snprintf(msg, sizeof msg, |
769 | 0 | "C_InitPIN(hSession=0x%08lX)=0x%08lX", |
770 | 0 | (PRUint32)hSession, (PRUint32)rv); |
771 | 0 | sftk_LogAuditMessage(severity, NSS_AUDIT_INIT_PIN, msg); |
772 | 0 | } |
773 | 0 | return rv; |
774 | 0 | } |
775 | | |
776 | | /* FC_SetPIN modifies the PIN of user that is currently logged in. */ |
777 | | /* NOTE: This is only valid for the PRIVATE_KEY_SLOT */ |
778 | | CK_RV |
779 | | FC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin, |
780 | | CK_ULONG usOldLen, CK_CHAR_PTR pNewPin, CK_ULONG usNewLen) |
781 | 0 | { |
782 | 0 | CK_RV rv; |
783 | |
|
784 | 0 | CHECK_FORK(); |
785 | |
|
786 | 0 | rv = sftk_fipsCheck(); |
787 | 0 | if (rv != CKR_OK) { |
788 | 0 | goto loser; |
789 | 0 | } |
790 | | |
791 | 0 | if (isLevel2 || usNewLen > 0) { |
792 | 0 | rv = sftk_newPinCheck(pNewPin, usNewLen); |
793 | 0 | if (rv != CKR_OK) { |
794 | 0 | goto loser; |
795 | 0 | } |
796 | 0 | rv = NSC_SetPIN(hSession, pOldPin, usOldLen, pNewPin, usNewLen); |
797 | 0 | if (rv != CKR_OK) { |
798 | 0 | goto loser; |
799 | 0 | } |
800 | 0 | if (sftk_SlotIDFromSessionHandle(hSession) == FIPS_SLOT_ID) { |
801 | | /* if we set the password in level1 we now go |
802 | | * to level2. NOTE: we don't allow the user to |
803 | | * go from level2 to level1 */ |
804 | 0 | isLevel2 = PR_TRUE; |
805 | 0 | } |
806 | 0 | } else { |
807 | | /* here both old and new passwords are empty, but we need to |
808 | | * call NSC_SetPIN to force rekey the database entries */ |
809 | 0 | PORT_Assert(usNewLen == 0); |
810 | 0 | rv = NSC_SetPIN(hSession, pOldPin, usOldLen, pNewPin, usNewLen); |
811 | 0 | if (rv != CKR_OK) { |
812 | 0 | goto loser; |
813 | 0 | } |
814 | 0 | } |
815 | | |
816 | 0 | loser: |
817 | 0 | if (sftk_audit_enabled) { |
818 | 0 | char msg[128]; |
819 | 0 | NSSAuditSeverity severity = (rv == CKR_OK) ? NSS_AUDIT_INFO : NSS_AUDIT_ERROR; |
820 | 0 | PR_snprintf(msg, sizeof msg, |
821 | 0 | "C_SetPIN(hSession=0x%08lX)=0x%08lX", |
822 | 0 | (PRUint32)hSession, (PRUint32)rv); |
823 | 0 | sftk_LogAuditMessage(severity, NSS_AUDIT_SET_PIN, msg); |
824 | 0 | } |
825 | 0 | return rv; |
826 | 0 | } |
827 | | |
828 | | /* FC_OpenSession opens a session between an application and a token. */ |
829 | | CK_RV |
830 | | FC_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags, |
831 | | CK_VOID_PTR pApplication, CK_NOTIFY Notify, CK_SESSION_HANDLE_PTR phSession) |
832 | 0 | { |
833 | 0 | SFTK_FIPSFATALCHECK(); |
834 | |
|
835 | 0 | CHECK_FORK(); |
836 | |
|
837 | 0 | return NSC_OpenSession(slotID, flags, pApplication, Notify, phSession); |
838 | 0 | } |
839 | | |
840 | | /* FC_CloseSession closes a session between an application and a token. */ |
841 | | CK_RV |
842 | | FC_CloseSession(CK_SESSION_HANDLE hSession) |
843 | 0 | { |
844 | 0 | CHECK_FORK(); |
845 | |
|
846 | 0 | return NSC_CloseSession(hSession); |
847 | 0 | } |
848 | | |
849 | | /* FC_CloseAllSessions closes all sessions with a token. */ |
850 | | CK_RV |
851 | | FC_CloseAllSessions(CK_SLOT_ID slotID) |
852 | 0 | { |
853 | |
|
854 | 0 | CHECK_FORK(); |
855 | |
|
856 | 0 | return NSC_CloseAllSessions(slotID); |
857 | 0 | } |
858 | | |
859 | | CK_RV |
860 | | FC_SessionCancel(CK_SESSION_HANDLE hSession, CK_FLAGS flags) |
861 | 0 | { |
862 | 0 | SFTK_FIPSFATALCHECK(); |
863 | |
|
864 | 0 | CHECK_FORK(); |
865 | |
|
866 | 0 | return NSC_SessionCancel(hSession, flags); |
867 | 0 | } |
868 | | |
869 | | /* FC_GetSessionInfo obtains information about the session. */ |
870 | | CK_RV |
871 | | FC_GetSessionInfo(CK_SESSION_HANDLE hSession, |
872 | | CK_SESSION_INFO_PTR pInfo) |
873 | 0 | { |
874 | 0 | CK_RV rv; |
875 | 0 | SFTK_FIPSFATALCHECK(); |
876 | |
|
877 | 0 | CHECK_FORK(); |
878 | |
|
879 | 0 | rv = NSC_GetSessionInfo(hSession, pInfo); |
880 | 0 | if (rv == CKR_OK) { |
881 | | /* handle the case where the auxilary slot doesn't require login. |
882 | | * piggy back on the main token's login state */ |
883 | 0 | if (isLoggedIn && |
884 | 0 | ((pInfo->state == CKS_RO_PUBLIC_SESSION) || |
885 | 0 | (pInfo->state == CKS_RW_PUBLIC_SESSION))) { |
886 | 0 | CK_RV crv; |
887 | 0 | CK_TOKEN_INFO tInfo; |
888 | 0 | crv = NSC_GetTokenInfo(sftk_SlotIDFromSessionHandle(hSession), |
889 | 0 | &tInfo); |
890 | | /* if the token doesn't login, use our global login state */ |
891 | 0 | if ((crv == CKR_OK) && ((tInfo.flags & CKF_LOGIN_REQUIRED) == 0)) { |
892 | 0 | if (pInfo->state == CKS_RO_PUBLIC_SESSION) { |
893 | 0 | pInfo->state = CKS_RO_USER_FUNCTIONS; |
894 | 0 | } else { |
895 | 0 | pInfo->state = CKS_RW_USER_FUNCTIONS; |
896 | 0 | } |
897 | 0 | } |
898 | 0 | } |
899 | 0 | } |
900 | 0 | return rv; |
901 | 0 | } |
902 | | |
903 | | /* FC_Login logs a user into a token. */ |
904 | | CK_RV |
905 | | FC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, |
906 | | CK_CHAR_PTR pPin, CK_ULONG usPinLen) |
907 | 0 | { |
908 | 0 | CK_RV rv; |
909 | 0 | PRBool successful; |
910 | 0 | if (sftk_fatalError) |
911 | 0 | return CKR_DEVICE_ERROR; |
912 | 0 | rv = NSC_Login(hSession, userType, pPin, usPinLen); |
913 | 0 | successful = (rv == CKR_OK) || (rv == CKR_USER_ALREADY_LOGGED_IN); |
914 | 0 | if (successful) |
915 | 0 | isLoggedIn = PR_TRUE; |
916 | 0 | if (sftk_audit_enabled) { |
917 | 0 | char msg[128]; |
918 | 0 | NSSAuditSeverity severity; |
919 | 0 | severity = successful ? NSS_AUDIT_INFO : NSS_AUDIT_ERROR; |
920 | 0 | PR_snprintf(msg, sizeof msg, |
921 | 0 | "C_Login(hSession=0x%08lX, userType=%lu)=0x%08lX", |
922 | 0 | (PRUint32)hSession, (PRUint32)userType, (PRUint32)rv); |
923 | 0 | sftk_LogAuditMessage(severity, NSS_AUDIT_LOGIN, msg); |
924 | 0 | } |
925 | 0 | return rv; |
926 | 0 | } |
927 | | |
928 | | CK_RV |
929 | | FC_LoginUser(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, |
930 | | CK_CHAR_PTR pPin, CK_ULONG ulPinLen, CK_UTF8CHAR_PTR pUsername, |
931 | | CK_ULONG ulUsernameLen) |
932 | 0 | { |
933 | 0 | CK_RV rv; |
934 | 0 | PRBool successful; |
935 | 0 | if (sftk_fatalError) |
936 | 0 | return CKR_DEVICE_ERROR; |
937 | 0 | rv = NSC_LoginUser(hSession, userType, pPin, ulPinLen, |
938 | 0 | pUsername, ulUsernameLen); |
939 | 0 | successful = (rv == CKR_OK) || (rv == CKR_USER_ALREADY_LOGGED_IN); |
940 | 0 | if (successful) |
941 | 0 | isLoggedIn = PR_TRUE; |
942 | 0 | if (sftk_audit_enabled) { |
943 | 0 | char msg[128]; |
944 | 0 | char user[61]; |
945 | 0 | int len = PR_MIN(ulUsernameLen, sizeof(user) - 1); |
946 | 0 | PORT_Memcpy(user, pUsername, len); |
947 | 0 | user[len] = 0; |
948 | 0 | NSSAuditSeverity severity; |
949 | 0 | severity = successful ? NSS_AUDIT_INFO : NSS_AUDIT_ERROR; |
950 | 0 | PR_snprintf(msg, sizeof msg, |
951 | 0 | "C_LoginUser(hSession=0x%08lX, userType=%lu username=%s)=0x%08lX", |
952 | 0 | (PRUint32)hSession, (PRUint32)userType, user, (PRUint32)rv); |
953 | 0 | sftk_LogAuditMessage(severity, NSS_AUDIT_LOGIN, msg); |
954 | 0 | } |
955 | 0 | return rv; |
956 | 0 | } |
957 | | |
958 | | /* FC_Logout logs a user out from a token. */ |
959 | | CK_RV |
960 | | FC_Logout(CK_SESSION_HANDLE hSession) |
961 | 0 | { |
962 | 0 | CK_RV rv; |
963 | |
|
964 | 0 | CHECK_FORK(); |
965 | |
|
966 | 0 | if ((rv = sftk_fipsCheck()) == CKR_OK) { |
967 | 0 | rv = NSC_Logout(hSession); |
968 | 0 | isLoggedIn = PR_FALSE; |
969 | 0 | } |
970 | 0 | if (sftk_audit_enabled) { |
971 | 0 | char msg[128]; |
972 | 0 | NSSAuditSeverity severity = (rv == CKR_OK) ? NSS_AUDIT_INFO : NSS_AUDIT_ERROR; |
973 | 0 | PR_snprintf(msg, sizeof msg, |
974 | 0 | "C_Logout(hSession=0x%08lX)=0x%08lX", |
975 | 0 | (PRUint32)hSession, (PRUint32)rv); |
976 | 0 | sftk_LogAuditMessage(severity, NSS_AUDIT_LOGOUT, msg); |
977 | 0 | } |
978 | 0 | return rv; |
979 | 0 | } |
980 | | |
981 | | /* FC_CreateObject creates a new object. */ |
982 | | CK_RV |
983 | | FC_CreateObject(CK_SESSION_HANDLE hSession, |
984 | | CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, |
985 | | CK_OBJECT_HANDLE_PTR phObject) |
986 | 0 | { |
987 | 0 | CK_OBJECT_CLASS *classptr; |
988 | 0 | CK_RV rv = CKR_OK; |
989 | |
|
990 | 0 | CHECK_FORK(); |
991 | |
|
992 | 0 | classptr = (CK_OBJECT_CLASS *)fc_getAttribute(pTemplate, ulCount, CKA_CLASS); |
993 | 0 | if (classptr == NULL) |
994 | 0 | return CKR_TEMPLATE_INCOMPLETE; |
995 | | |
996 | 0 | if (*classptr == CKO_NSS_NEWSLOT || *classptr == CKO_NSS_DELSLOT) { |
997 | 0 | if (sftk_fatalError) |
998 | 0 | return CKR_DEVICE_ERROR; |
999 | 0 | } else { |
1000 | 0 | rv = sftk_fipsCheck(); |
1001 | 0 | if (rv != CKR_OK) |
1002 | 0 | return rv; |
1003 | 0 | } |
1004 | | |
1005 | | /* FIPS can't create keys from raw key material */ |
1006 | 0 | if (SFTK_IS_NONPUBLIC_KEY_OBJECT(*classptr)) { |
1007 | 0 | rv = CKR_ATTRIBUTE_VALUE_INVALID; |
1008 | 0 | } else { |
1009 | 0 | rv = NSC_CreateObject(hSession, pTemplate, ulCount, phObject); |
1010 | 0 | } |
1011 | 0 | if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(*classptr)) { |
1012 | 0 | sftk_AuditCreateObject(hSession, pTemplate, ulCount, phObject, rv); |
1013 | 0 | } |
1014 | 0 | return rv; |
1015 | 0 | } |
1016 | | |
1017 | | /* FC_CopyObject copies an object, creating a new object for the copy. */ |
1018 | | CK_RV |
1019 | | FC_CopyObject(CK_SESSION_HANDLE hSession, |
1020 | | CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, |
1021 | | CK_OBJECT_HANDLE_PTR phNewObject) |
1022 | 0 | { |
1023 | 0 | CK_RV rv; |
1024 | 0 | CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY; |
1025 | |
|
1026 | 0 | CHECK_FORK(); |
1027 | |
|
1028 | 0 | SFTK_FIPSFATALCHECK(); |
1029 | 0 | rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass); |
1030 | 0 | if (rv == CKR_OK) { |
1031 | 0 | rv = NSC_CopyObject(hSession, hObject, pTemplate, ulCount, phNewObject); |
1032 | 0 | } |
1033 | 0 | if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) { |
1034 | 0 | sftk_AuditCopyObject(hSession, |
1035 | 0 | hObject, pTemplate, ulCount, phNewObject, rv); |
1036 | 0 | } |
1037 | 0 | return rv; |
1038 | 0 | } |
1039 | | |
1040 | | /* FC_DestroyObject destroys an object. */ |
1041 | | CK_RV |
1042 | | FC_DestroyObject(CK_SESSION_HANDLE hSession, |
1043 | | CK_OBJECT_HANDLE hObject) |
1044 | 0 | { |
1045 | 0 | CK_RV rv; |
1046 | 0 | CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY; |
1047 | |
|
1048 | 0 | CHECK_FORK(); |
1049 | |
|
1050 | 0 | SFTK_FIPSFATALCHECK(); |
1051 | 0 | rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass); |
1052 | 0 | if (rv == CKR_OK) { |
1053 | 0 | rv = NSC_DestroyObject(hSession, hObject); |
1054 | 0 | } |
1055 | 0 | if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) { |
1056 | 0 | sftk_AuditDestroyObject(hSession, hObject, rv); |
1057 | 0 | } |
1058 | 0 | return rv; |
1059 | 0 | } |
1060 | | |
1061 | | /* FC_GetObjectSize gets the size of an object in bytes. */ |
1062 | | CK_RV |
1063 | | FC_GetObjectSize(CK_SESSION_HANDLE hSession, |
1064 | | CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize) |
1065 | 0 | { |
1066 | 0 | CK_RV rv; |
1067 | 0 | CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY; |
1068 | |
|
1069 | 0 | CHECK_FORK(); |
1070 | |
|
1071 | 0 | SFTK_FIPSFATALCHECK(); |
1072 | 0 | rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass); |
1073 | 0 | if (rv == CKR_OK) { |
1074 | 0 | rv = NSC_GetObjectSize(hSession, hObject, pulSize); |
1075 | 0 | } |
1076 | 0 | if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) { |
1077 | 0 | sftk_AuditGetObjectSize(hSession, hObject, pulSize, rv); |
1078 | 0 | } |
1079 | 0 | return rv; |
1080 | 0 | } |
1081 | | |
1082 | | /* FC_GetAttributeValue obtains the value of one or more object attributes. */ |
1083 | | CK_RV |
1084 | | FC_GetAttributeValue(CK_SESSION_HANDLE hSession, |
1085 | | CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) |
1086 | 0 | { |
1087 | 0 | CK_RV rv; |
1088 | 0 | CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY; |
1089 | |
|
1090 | 0 | CHECK_FORK(); |
1091 | |
|
1092 | 0 | SFTK_FIPSFATALCHECK(); |
1093 | 0 | rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass); |
1094 | 0 | if (rv == CKR_OK) { |
1095 | 0 | rv = NSC_GetAttributeValue(hSession, hObject, pTemplate, ulCount); |
1096 | 0 | } |
1097 | 0 | if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) { |
1098 | 0 | sftk_AuditGetAttributeValue(hSession, hObject, pTemplate, ulCount, rv); |
1099 | 0 | } |
1100 | 0 | return rv; |
1101 | 0 | } |
1102 | | |
1103 | | /* FC_SetAttributeValue modifies the value of one or more object attributes */ |
1104 | | CK_RV |
1105 | | FC_SetAttributeValue(CK_SESSION_HANDLE hSession, |
1106 | | CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) |
1107 | 0 | { |
1108 | 0 | CK_RV rv; |
1109 | 0 | CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY; |
1110 | |
|
1111 | 0 | CHECK_FORK(); |
1112 | |
|
1113 | 0 | SFTK_FIPSFATALCHECK(); |
1114 | 0 | rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass); |
1115 | 0 | if (rv == CKR_OK) { |
1116 | 0 | rv = NSC_SetAttributeValue(hSession, hObject, pTemplate, ulCount); |
1117 | 0 | } |
1118 | 0 | if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) { |
1119 | 0 | sftk_AuditSetAttributeValue(hSession, hObject, pTemplate, ulCount, rv); |
1120 | 0 | } |
1121 | 0 | return rv; |
1122 | 0 | } |
1123 | | |
1124 | | /* FC_FindObjectsInit initializes a search for token and session objects |
1125 | | * that match a template. */ |
1126 | | CK_RV |
1127 | | FC_FindObjectsInit(CK_SESSION_HANDLE hSession, |
1128 | | CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount) |
1129 | 0 | { |
1130 | | /* let publically readable object be found */ |
1131 | 0 | unsigned int i; |
1132 | 0 | CK_RV rv; |
1133 | 0 | PRBool needLogin = PR_FALSE; |
1134 | |
|
1135 | 0 | CHECK_FORK(); |
1136 | |
|
1137 | 0 | SFTK_FIPSFATALCHECK(); |
1138 | |
|
1139 | 0 | for (i = 0; i < usCount; i++) { |
1140 | 0 | CK_OBJECT_CLASS class; |
1141 | 0 | if (pTemplate[i].type != CKA_CLASS) { |
1142 | 0 | continue; |
1143 | 0 | } |
1144 | 0 | if (pTemplate[i].ulValueLen != sizeof(CK_OBJECT_CLASS)) { |
1145 | 0 | continue; |
1146 | 0 | } |
1147 | 0 | if (pTemplate[i].pValue == NULL) { |
1148 | 0 | continue; |
1149 | 0 | } |
1150 | 0 | class = *(CK_OBJECT_CLASS *)pTemplate[i].pValue; |
1151 | 0 | if ((class == CKO_PRIVATE_KEY) || (class == CKO_SECRET_KEY)) { |
1152 | 0 | needLogin = PR_TRUE; |
1153 | 0 | break; |
1154 | 0 | } |
1155 | 0 | } |
1156 | 0 | if (needLogin) { |
1157 | 0 | if ((rv = sftk_fipsCheck()) != CKR_OK) |
1158 | 0 | return rv; |
1159 | 0 | } |
1160 | 0 | return NSC_FindObjectsInit(hSession, pTemplate, usCount); |
1161 | 0 | } |
1162 | | |
1163 | | /* FC_FindObjects continues a search for token and session objects |
1164 | | * that match a template, obtaining additional object handles. */ |
1165 | | CK_RV |
1166 | | FC_FindObjects(CK_SESSION_HANDLE hSession, |
1167 | | CK_OBJECT_HANDLE_PTR phObject, CK_ULONG usMaxObjectCount, |
1168 | | CK_ULONG_PTR pusObjectCount) |
1169 | 0 | { |
1170 | 0 | CHECK_FORK(); |
1171 | | |
1172 | | /* let publically readable object be found */ |
1173 | 0 | SFTK_FIPSFATALCHECK(); |
1174 | 0 | return NSC_FindObjects(hSession, phObject, usMaxObjectCount, |
1175 | 0 | pusObjectCount); |
1176 | 0 | } |
1177 | | |
1178 | | /* |
1179 | | ************** Crypto Functions: Encrypt ************************ |
1180 | | */ |
1181 | | |
1182 | | /* FC_EncryptInit initializes an encryption operation. */ |
1183 | | CK_RV |
1184 | | FC_EncryptInit(CK_SESSION_HANDLE hSession, |
1185 | | CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) |
1186 | 0 | { |
1187 | 0 | SFTK_FIPSCHECK(); |
1188 | 0 | CHECK_FORK(); |
1189 | |
|
1190 | 0 | rv = NSC_EncryptInit(hSession, pMechanism, hKey); |
1191 | 0 | if (sftk_audit_enabled) { |
1192 | 0 | sftk_AuditCryptInit("Encrypt", hSession, pMechanism, hKey, rv); |
1193 | 0 | } |
1194 | 0 | return rv; |
1195 | 0 | } |
1196 | | |
1197 | | /* FC_Encrypt encrypts single-part data. */ |
1198 | | CK_RV |
1199 | | FC_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, |
1200 | | CK_ULONG usDataLen, CK_BYTE_PTR pEncryptedData, |
1201 | | CK_ULONG_PTR pusEncryptedDataLen) |
1202 | 0 | { |
1203 | 0 | SFTK_FIPSCHECK(); |
1204 | 0 | CHECK_FORK(); |
1205 | |
|
1206 | 0 | return NSC_Encrypt(hSession, pData, usDataLen, pEncryptedData, |
1207 | 0 | pusEncryptedDataLen); |
1208 | 0 | } |
1209 | | |
1210 | | /* FC_EncryptUpdate continues a multiple-part encryption operation. */ |
1211 | | CK_RV |
1212 | | FC_EncryptUpdate(CK_SESSION_HANDLE hSession, |
1213 | | CK_BYTE_PTR pPart, CK_ULONG usPartLen, CK_BYTE_PTR pEncryptedPart, |
1214 | | CK_ULONG_PTR pusEncryptedPartLen) |
1215 | 0 | { |
1216 | 0 | SFTK_FIPSCHECK(); |
1217 | 0 | CHECK_FORK(); |
1218 | |
|
1219 | 0 | return NSC_EncryptUpdate(hSession, pPart, usPartLen, pEncryptedPart, |
1220 | 0 | pusEncryptedPartLen); |
1221 | 0 | } |
1222 | | |
1223 | | /* FC_EncryptFinal finishes a multiple-part encryption operation. */ |
1224 | | CK_RV |
1225 | | FC_EncryptFinal(CK_SESSION_HANDLE hSession, |
1226 | | CK_BYTE_PTR pLastEncryptedPart, CK_ULONG_PTR pusLastEncryptedPartLen) |
1227 | 0 | { |
1228 | 0 | SFTK_FIPSCHECK(); |
1229 | 0 | CHECK_FORK(); |
1230 | |
|
1231 | 0 | return NSC_EncryptFinal(hSession, pLastEncryptedPart, |
1232 | 0 | pusLastEncryptedPartLen); |
1233 | 0 | } |
1234 | | |
1235 | | /* |
1236 | | ************** Crypto Functions: Decrypt ************************ |
1237 | | */ |
1238 | | |
1239 | | /* FC_DecryptInit initializes a decryption operation. */ |
1240 | | CK_RV |
1241 | | FC_DecryptInit(CK_SESSION_HANDLE hSession, |
1242 | | CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) |
1243 | 0 | { |
1244 | 0 | SFTK_FIPSCHECK(); |
1245 | 0 | CHECK_FORK(); |
1246 | |
|
1247 | 0 | rv = NSC_DecryptInit(hSession, pMechanism, hKey); |
1248 | 0 | if (sftk_audit_enabled) { |
1249 | 0 | sftk_AuditCryptInit("Decrypt", hSession, pMechanism, hKey, rv); |
1250 | 0 | } |
1251 | 0 | return rv; |
1252 | 0 | } |
1253 | | |
1254 | | /* FC_Decrypt decrypts encrypted data in a single part. */ |
1255 | | CK_RV |
1256 | | FC_Decrypt(CK_SESSION_HANDLE hSession, |
1257 | | CK_BYTE_PTR pEncryptedData, CK_ULONG usEncryptedDataLen, CK_BYTE_PTR pData, |
1258 | | CK_ULONG_PTR pusDataLen) |
1259 | 0 | { |
1260 | 0 | SFTK_FIPSCHECK(); |
1261 | 0 | CHECK_FORK(); |
1262 | |
|
1263 | 0 | return NSC_Decrypt(hSession, pEncryptedData, usEncryptedDataLen, pData, |
1264 | 0 | pusDataLen); |
1265 | 0 | } |
1266 | | |
1267 | | /* FC_DecryptUpdate continues a multiple-part decryption operation. */ |
1268 | | CK_RV |
1269 | | FC_DecryptUpdate(CK_SESSION_HANDLE hSession, |
1270 | | CK_BYTE_PTR pEncryptedPart, CK_ULONG usEncryptedPartLen, |
1271 | | CK_BYTE_PTR pPart, CK_ULONG_PTR pusPartLen) |
1272 | 0 | { |
1273 | 0 | SFTK_FIPSCHECK(); |
1274 | 0 | CHECK_FORK(); |
1275 | |
|
1276 | 0 | return NSC_DecryptUpdate(hSession, pEncryptedPart, usEncryptedPartLen, |
1277 | 0 | pPart, pusPartLen); |
1278 | 0 | } |
1279 | | |
1280 | | /* FC_DecryptFinal finishes a multiple-part decryption operation. */ |
1281 | | CK_RV |
1282 | | FC_DecryptFinal(CK_SESSION_HANDLE hSession, |
1283 | | CK_BYTE_PTR pLastPart, CK_ULONG_PTR pusLastPartLen) |
1284 | 0 | { |
1285 | 0 | SFTK_FIPSCHECK(); |
1286 | 0 | CHECK_FORK(); |
1287 | |
|
1288 | 0 | return NSC_DecryptFinal(hSession, pLastPart, pusLastPartLen); |
1289 | 0 | } |
1290 | | |
1291 | | /* |
1292 | | ************** Crypto Functions: Digest (HASH) ************************ |
1293 | | */ |
1294 | | |
1295 | | /* FC_DigestInit initializes a message-digesting operation. */ |
1296 | | CK_RV |
1297 | | FC_DigestInit(CK_SESSION_HANDLE hSession, |
1298 | | CK_MECHANISM_PTR pMechanism) |
1299 | 0 | { |
1300 | 0 | SFTK_FIPSFATALCHECK(); |
1301 | 0 | CHECK_FORK(); |
1302 | |
|
1303 | 0 | return NSC_DigestInit(hSession, pMechanism); |
1304 | 0 | } |
1305 | | |
1306 | | /* FC_Digest digests data in a single part. */ |
1307 | | CK_RV |
1308 | | FC_Digest(CK_SESSION_HANDLE hSession, |
1309 | | CK_BYTE_PTR pData, CK_ULONG usDataLen, CK_BYTE_PTR pDigest, |
1310 | | CK_ULONG_PTR pusDigestLen) |
1311 | 0 | { |
1312 | 0 | SFTK_FIPSFATALCHECK(); |
1313 | 0 | CHECK_FORK(); |
1314 | |
|
1315 | 0 | return NSC_Digest(hSession, pData, usDataLen, pDigest, pusDigestLen); |
1316 | 0 | } |
1317 | | |
1318 | | /* FC_DigestUpdate continues a multiple-part message-digesting operation. */ |
1319 | | CK_RV |
1320 | | FC_DigestUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, |
1321 | | CK_ULONG usPartLen) |
1322 | 0 | { |
1323 | 0 | SFTK_FIPSFATALCHECK(); |
1324 | 0 | CHECK_FORK(); |
1325 | |
|
1326 | 0 | return NSC_DigestUpdate(hSession, pPart, usPartLen); |
1327 | 0 | } |
1328 | | |
1329 | | /* FC_DigestFinal finishes a multiple-part message-digesting operation. */ |
1330 | | CK_RV |
1331 | | FC_DigestFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest, |
1332 | | CK_ULONG_PTR pusDigestLen) |
1333 | 0 | { |
1334 | 0 | SFTK_FIPSFATALCHECK(); |
1335 | 0 | CHECK_FORK(); |
1336 | |
|
1337 | 0 | return NSC_DigestFinal(hSession, pDigest, pusDigestLen); |
1338 | 0 | } |
1339 | | |
1340 | | /* |
1341 | | ************** Crypto Functions: Sign ************************ |
1342 | | */ |
1343 | | |
1344 | | /* FC_SignInit initializes a signature (private key encryption) operation, |
1345 | | * where the signature is (will be) an appendix to the data, |
1346 | | * and plaintext cannot be recovered from the signature */ |
1347 | | CK_RV |
1348 | | FC_SignInit(CK_SESSION_HANDLE hSession, |
1349 | | CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) |
1350 | 0 | { |
1351 | 0 | SFTK_FIPSCHECK(); |
1352 | 0 | CHECK_FORK(); |
1353 | |
|
1354 | 0 | rv = NSC_SignInit(hSession, pMechanism, hKey); |
1355 | 0 | if (sftk_audit_enabled) { |
1356 | 0 | sftk_AuditCryptInit("Sign", hSession, pMechanism, hKey, rv); |
1357 | 0 | } |
1358 | 0 | return rv; |
1359 | 0 | } |
1360 | | |
1361 | | /* FC_Sign signs (encrypts with private key) data in a single part, |
1362 | | * where the signature is (will be) an appendix to the data, |
1363 | | * and plaintext cannot be recovered from the signature */ |
1364 | | CK_RV |
1365 | | FC_Sign(CK_SESSION_HANDLE hSession, |
1366 | | CK_BYTE_PTR pData, CK_ULONG usDataLen, CK_BYTE_PTR pSignature, |
1367 | | CK_ULONG_PTR pusSignatureLen) |
1368 | 0 | { |
1369 | 0 | SFTK_FIPSCHECK(); |
1370 | 0 | CHECK_FORK(); |
1371 | |
|
1372 | 0 | return NSC_Sign(hSession, pData, usDataLen, pSignature, pusSignatureLen); |
1373 | 0 | } |
1374 | | |
1375 | | /* FC_SignUpdate continues a multiple-part signature operation, |
1376 | | * where the signature is (will be) an appendix to the data, |
1377 | | * and plaintext cannot be recovered from the signature */ |
1378 | | CK_RV |
1379 | | FC_SignUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, |
1380 | | CK_ULONG usPartLen) |
1381 | 0 | { |
1382 | 0 | SFTK_FIPSCHECK(); |
1383 | 0 | CHECK_FORK(); |
1384 | |
|
1385 | 0 | return NSC_SignUpdate(hSession, pPart, usPartLen); |
1386 | 0 | } |
1387 | | |
1388 | | /* FC_SignFinal finishes a multiple-part signature operation, |
1389 | | * returning the signature. */ |
1390 | | CK_RV |
1391 | | FC_SignFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, |
1392 | | CK_ULONG_PTR pusSignatureLen) |
1393 | 0 | { |
1394 | 0 | SFTK_FIPSCHECK(); |
1395 | 0 | CHECK_FORK(); |
1396 | |
|
1397 | 0 | return NSC_SignFinal(hSession, pSignature, pusSignatureLen); |
1398 | 0 | } |
1399 | | |
1400 | | /* |
1401 | | ************** Crypto Functions: Sign Recover ************************ |
1402 | | */ |
1403 | | /* FC_SignRecoverInit initializes a signature operation, |
1404 | | * where the (digest) data can be recovered from the signature. |
1405 | | * E.g. encryption with the user's private key */ |
1406 | | CK_RV |
1407 | | FC_SignRecoverInit(CK_SESSION_HANDLE hSession, |
1408 | | CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) |
1409 | 0 | { |
1410 | 0 | SFTK_FIPSCHECK(); |
1411 | 0 | CHECK_FORK(); |
1412 | |
|
1413 | 0 | rv = NSC_SignRecoverInit(hSession, pMechanism, hKey); |
1414 | 0 | if (sftk_audit_enabled) { |
1415 | 0 | sftk_AuditCryptInit("SignRecover", hSession, pMechanism, hKey, rv); |
1416 | 0 | } |
1417 | 0 | return rv; |
1418 | 0 | } |
1419 | | |
1420 | | /* FC_SignRecover signs data in a single operation |
1421 | | * where the (digest) data can be recovered from the signature. |
1422 | | * E.g. encryption with the user's private key */ |
1423 | | CK_RV |
1424 | | FC_SignRecover(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, |
1425 | | CK_ULONG usDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pusSignatureLen) |
1426 | 0 | { |
1427 | 0 | SFTK_FIPSCHECK(); |
1428 | 0 | CHECK_FORK(); |
1429 | |
|
1430 | 0 | return NSC_SignRecover(hSession, pData, usDataLen, pSignature, pusSignatureLen); |
1431 | 0 | } |
1432 | | |
1433 | | /* |
1434 | | ************** Crypto Functions: verify ************************ |
1435 | | */ |
1436 | | |
1437 | | /* FC_VerifyInit initializes a verification operation, |
1438 | | * where the signature is an appendix to the data, |
1439 | | * and plaintext cannot be recovered from the signature (e.g. DSA) */ |
1440 | | CK_RV |
1441 | | FC_VerifyInit(CK_SESSION_HANDLE hSession, |
1442 | | CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) |
1443 | 0 | { |
1444 | 0 | SFTK_FIPSCHECK(); |
1445 | 0 | CHECK_FORK(); |
1446 | |
|
1447 | 0 | rv = NSC_VerifyInit(hSession, pMechanism, hKey); |
1448 | 0 | if (sftk_audit_enabled) { |
1449 | 0 | sftk_AuditCryptInit("Verify", hSession, pMechanism, hKey, rv); |
1450 | 0 | } |
1451 | 0 | return rv; |
1452 | 0 | } |
1453 | | |
1454 | | /* FC_Verify verifies a signature in a single-part operation, |
1455 | | * where the signature is an appendix to the data, |
1456 | | * and plaintext cannot be recovered from the signature */ |
1457 | | CK_RV |
1458 | | FC_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, |
1459 | | CK_ULONG usDataLen, CK_BYTE_PTR pSignature, CK_ULONG usSignatureLen) |
1460 | 0 | { |
1461 | | /* make sure we're legal */ |
1462 | 0 | SFTK_FIPSCHECK(); |
1463 | 0 | CHECK_FORK(); |
1464 | |
|
1465 | 0 | return NSC_Verify(hSession, pData, usDataLen, pSignature, usSignatureLen); |
1466 | 0 | } |
1467 | | |
1468 | | /* FC_VerifyUpdate continues a multiple-part verification operation, |
1469 | | * where the signature is an appendix to the data, |
1470 | | * and plaintext cannot be recovered from the signature */ |
1471 | | CK_RV |
1472 | | FC_VerifyUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, |
1473 | | CK_ULONG usPartLen) |
1474 | 0 | { |
1475 | 0 | SFTK_FIPSCHECK(); |
1476 | 0 | CHECK_FORK(); |
1477 | |
|
1478 | 0 | return NSC_VerifyUpdate(hSession, pPart, usPartLen); |
1479 | 0 | } |
1480 | | |
1481 | | /* FC_VerifyFinal finishes a multiple-part verification operation, |
1482 | | * checking the signature. */ |
1483 | | CK_RV |
1484 | | FC_VerifyFinal(CK_SESSION_HANDLE hSession, |
1485 | | CK_BYTE_PTR pSignature, CK_ULONG usSignatureLen) |
1486 | 0 | { |
1487 | 0 | SFTK_FIPSCHECK(); |
1488 | 0 | CHECK_FORK(); |
1489 | |
|
1490 | 0 | return NSC_VerifyFinal(hSession, pSignature, usSignatureLen); |
1491 | 0 | } |
1492 | | |
1493 | | /* |
1494 | | ************** Crypto Functions: Verify Signature ************************ |
1495 | | * some algorithms need the signature at the beginning of the verification, |
1496 | | * VerifySignature provides such and API. For algorithms that don't need |
1497 | | * the signature first, we stash the signature and just pass it to |
1498 | | * NSC_VerifyXXX. |
1499 | | */ |
1500 | | CK_RV |
1501 | | FC_VerifySignatureInit(CK_SESSION_HANDLE hSession, |
1502 | | CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey, |
1503 | | CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen) |
1504 | 0 | { |
1505 | 0 | SFTK_FIPSCHECK(); |
1506 | 0 | CHECK_FORK(); |
1507 | |
|
1508 | 0 | rv = NSC_VerifySignatureInit(hSession, pMechanism, hKey, |
1509 | 0 | pSignature, ulSignatureLen); |
1510 | 0 | if (sftk_audit_enabled) { |
1511 | 0 | sftk_AuditCryptInit("VerifySignature", hSession, pMechanism, hKey, rv); |
1512 | 0 | } |
1513 | 0 | return rv; |
1514 | 0 | } |
1515 | | |
1516 | | CK_RV |
1517 | | FC_VerifySignature(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, |
1518 | | CK_ULONG ulDataLen) |
1519 | 0 | { |
1520 | 0 | SFTK_FIPSCHECK(); |
1521 | 0 | CHECK_FORK(); |
1522 | |
|
1523 | 0 | return NSC_VerifySignature(hSession, pData, ulDataLen); |
1524 | 0 | } |
1525 | | |
1526 | | CK_RV |
1527 | | FC_VerifySignatureUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, |
1528 | | CK_ULONG ulPartLen) |
1529 | 0 | { |
1530 | 0 | SFTK_FIPSCHECK(); |
1531 | 0 | CHECK_FORK(); |
1532 | |
|
1533 | 0 | return NSC_VerifySignatureUpdate(hSession, pPart, ulPartLen); |
1534 | 0 | } |
1535 | | |
1536 | | CK_RV |
1537 | | FC_VerifySignatureFinal(CK_SESSION_HANDLE hSession) |
1538 | 0 | { |
1539 | 0 | SFTK_FIPSCHECK(); |
1540 | 0 | CHECK_FORK(); |
1541 | |
|
1542 | 0 | return NSC_VerifySignatureFinal(hSession); |
1543 | 0 | } |
1544 | | |
1545 | | /* |
1546 | | ************** Crypto Functions: Verify Recover ************************ |
1547 | | */ |
1548 | | |
1549 | | /* FC_VerifyRecoverInit initializes a signature verification operation, |
1550 | | * where the data is recovered from the signature. |
1551 | | * E.g. Decryption with the user's public key */ |
1552 | | CK_RV |
1553 | | FC_VerifyRecoverInit(CK_SESSION_HANDLE hSession, |
1554 | | CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) |
1555 | 0 | { |
1556 | 0 | SFTK_FIPSCHECK(); |
1557 | 0 | CHECK_FORK(); |
1558 | |
|
1559 | 0 | rv = NSC_VerifyRecoverInit(hSession, pMechanism, hKey); |
1560 | 0 | if (sftk_audit_enabled) { |
1561 | 0 | sftk_AuditCryptInit("VerifyRecover", hSession, pMechanism, hKey, rv); |
1562 | 0 | } |
1563 | 0 | return rv; |
1564 | 0 | } |
1565 | | |
1566 | | /* FC_VerifyRecover verifies a signature in a single-part operation, |
1567 | | * where the data is recovered from the signature. |
1568 | | * E.g. Decryption with the user's public key */ |
1569 | | CK_RV |
1570 | | FC_VerifyRecover(CK_SESSION_HANDLE hSession, |
1571 | | CK_BYTE_PTR pSignature, CK_ULONG usSignatureLen, |
1572 | | CK_BYTE_PTR pData, CK_ULONG_PTR pusDataLen) |
1573 | 0 | { |
1574 | 0 | SFTK_FIPSCHECK(); |
1575 | 0 | CHECK_FORK(); |
1576 | |
|
1577 | 0 | return NSC_VerifyRecover(hSession, pSignature, usSignatureLen, pData, |
1578 | 0 | pusDataLen); |
1579 | 0 | } |
1580 | | |
1581 | | /* |
1582 | | **************************** Key Functions: ************************ |
1583 | | */ |
1584 | | |
1585 | | /* FC_GenerateKey generates a secret key, creating a new key object. */ |
1586 | | CK_RV |
1587 | | FC_GenerateKey(CK_SESSION_HANDLE hSession, |
1588 | | CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, |
1589 | | CK_OBJECT_HANDLE_PTR phKey) |
1590 | 0 | { |
1591 | 0 | CK_BBOOL *boolptr; |
1592 | |
|
1593 | 0 | SFTK_FIPSCHECK(); |
1594 | 0 | CHECK_FORK(); |
1595 | | |
1596 | | /* all secret keys must be sensitive, if the upper level code tries to say |
1597 | | * otherwise, reject it. */ |
1598 | 0 | boolptr = (CK_BBOOL *)fc_getAttribute(pTemplate, ulCount, CKA_SENSITIVE); |
1599 | 0 | if (boolptr != NULL) { |
1600 | 0 | if (!(*boolptr)) { |
1601 | 0 | return CKR_ATTRIBUTE_VALUE_INVALID; |
1602 | 0 | } |
1603 | 0 | } |
1604 | | |
1605 | 0 | rv = NSC_GenerateKey(hSession, pMechanism, pTemplate, ulCount, phKey); |
1606 | 0 | if (sftk_audit_enabled) { |
1607 | 0 | sftk_AuditGenerateKey(hSession, pMechanism, pTemplate, ulCount, phKey, rv); |
1608 | 0 | } |
1609 | 0 | return rv; |
1610 | 0 | } |
1611 | | |
1612 | | /* FC_GenerateKeyPair generates a public-key/private-key pair, |
1613 | | * creating new key objects. */ |
1614 | | CK_RV |
1615 | | FC_GenerateKeyPair(CK_SESSION_HANDLE hSession, |
1616 | | CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate, |
1617 | | CK_ULONG usPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate, |
1618 | | CK_ULONG usPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPublicKey, |
1619 | | CK_OBJECT_HANDLE_PTR phPrivateKey) |
1620 | 0 | { |
1621 | 0 | CK_BBOOL *boolptr; |
1622 | 0 | CK_RV crv; |
1623 | |
|
1624 | 0 | SFTK_FIPSCHECK(); |
1625 | 0 | CHECK_FORK(); |
1626 | | |
1627 | | /* all private keys must be sensitive, if the upper level code tries to say |
1628 | | * otherwise, reject it. */ |
1629 | 0 | boolptr = (CK_BBOOL *)fc_getAttribute(pPrivateKeyTemplate, |
1630 | 0 | usPrivateKeyAttributeCount, CKA_SENSITIVE); |
1631 | 0 | if (boolptr != NULL) { |
1632 | 0 | if (!(*boolptr)) { |
1633 | 0 | return CKR_ATTRIBUTE_VALUE_INVALID; |
1634 | 0 | } |
1635 | 0 | } |
1636 | 0 | crv = NSC_GenerateKeyPair(hSession, pMechanism, pPublicKeyTemplate, |
1637 | 0 | usPublicKeyAttributeCount, pPrivateKeyTemplate, |
1638 | 0 | usPrivateKeyAttributeCount, phPublicKey, phPrivateKey); |
1639 | 0 | if (crv == CKR_GENERAL_ERROR) { |
1640 | | /* pairwise consistency check failed. */ |
1641 | 0 | sftk_fatalError = PR_TRUE; |
1642 | 0 | } |
1643 | 0 | if (sftk_audit_enabled) { |
1644 | 0 | sftk_AuditGenerateKeyPair(hSession, pMechanism, pPublicKeyTemplate, |
1645 | 0 | usPublicKeyAttributeCount, pPrivateKeyTemplate, |
1646 | 0 | usPrivateKeyAttributeCount, phPublicKey, phPrivateKey, crv); |
1647 | 0 | } |
1648 | 0 | return crv; |
1649 | 0 | } |
1650 | | |
1651 | | /* FC_WrapKey wraps (i.e., encrypts) a key. */ |
1652 | | CK_RV |
1653 | | FC_WrapKey(CK_SESSION_HANDLE hSession, |
1654 | | CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey, |
1655 | | CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey, |
1656 | | CK_ULONG_PTR pulWrappedKeyLen) |
1657 | 0 | { |
1658 | 0 | SFTK_FIPSCHECK(); |
1659 | 0 | CHECK_FORK(); |
1660 | |
|
1661 | 0 | rv = NSC_WrapKey(hSession, pMechanism, hWrappingKey, hKey, pWrappedKey, |
1662 | 0 | pulWrappedKeyLen); |
1663 | 0 | if (sftk_audit_enabled) { |
1664 | 0 | sftk_AuditWrapKey(hSession, pMechanism, hWrappingKey, hKey, pWrappedKey, |
1665 | 0 | pulWrappedKeyLen, rv); |
1666 | 0 | } |
1667 | 0 | return rv; |
1668 | 0 | } |
1669 | | |
1670 | | /* FC_UnwrapKey unwraps (decrypts) a wrapped key, creating a new key object. */ |
1671 | | CK_RV |
1672 | | FC_UnwrapKey(CK_SESSION_HANDLE hSession, |
1673 | | CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey, |
1674 | | CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen, |
1675 | | CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, |
1676 | | CK_OBJECT_HANDLE_PTR phKey) |
1677 | 0 | { |
1678 | 0 | CK_BBOOL *boolptr; |
1679 | |
|
1680 | 0 | SFTK_FIPSCHECK(); |
1681 | 0 | CHECK_FORK(); |
1682 | | |
1683 | | /* all secret keys must be sensitive, if the upper level code tries to say |
1684 | | * otherwise, reject it. */ |
1685 | 0 | boolptr = (CK_BBOOL *)fc_getAttribute(pTemplate, |
1686 | 0 | ulAttributeCount, CKA_SENSITIVE); |
1687 | 0 | if (boolptr != NULL) { |
1688 | 0 | if (!(*boolptr)) { |
1689 | 0 | return CKR_ATTRIBUTE_VALUE_INVALID; |
1690 | 0 | } |
1691 | 0 | } |
1692 | 0 | rv = NSC_UnwrapKey(hSession, pMechanism, hUnwrappingKey, pWrappedKey, |
1693 | 0 | ulWrappedKeyLen, pTemplate, ulAttributeCount, phKey); |
1694 | 0 | if (sftk_audit_enabled) { |
1695 | 0 | sftk_AuditUnwrapKey(hSession, pMechanism, hUnwrappingKey, pWrappedKey, |
1696 | 0 | ulWrappedKeyLen, pTemplate, ulAttributeCount, phKey, rv); |
1697 | 0 | } |
1698 | 0 | return rv; |
1699 | 0 | } |
1700 | | |
1701 | | /* FC_DeriveKey derives a key from a base key, creating a new key object. */ |
1702 | | CK_RV |
1703 | | FC_DeriveKey(CK_SESSION_HANDLE hSession, |
1704 | | CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey, |
1705 | | CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, |
1706 | | CK_OBJECT_HANDLE_PTR phKey) |
1707 | 0 | { |
1708 | 0 | CK_BBOOL *boolptr; |
1709 | |
|
1710 | 0 | SFTK_FIPSCHECK(); |
1711 | 0 | CHECK_FORK(); |
1712 | | |
1713 | | /* all secret keys must be sensitive, if the upper level code tries to say |
1714 | | * otherwise, reject it. */ |
1715 | 0 | boolptr = (CK_BBOOL *)fc_getAttribute(pTemplate, |
1716 | 0 | ulAttributeCount, CKA_SENSITIVE); |
1717 | 0 | if (boolptr != NULL) { |
1718 | 0 | if (!(*boolptr)) { |
1719 | 0 | return CKR_ATTRIBUTE_VALUE_INVALID; |
1720 | 0 | } |
1721 | 0 | } |
1722 | 0 | rv = NSC_DeriveKey(hSession, pMechanism, hBaseKey, pTemplate, |
1723 | 0 | ulAttributeCount, phKey); |
1724 | 0 | if (sftk_audit_enabled) { |
1725 | 0 | sftk_AuditDeriveKey(hSession, pMechanism, hBaseKey, pTemplate, |
1726 | 0 | ulAttributeCount, phKey, rv); |
1727 | 0 | } |
1728 | 0 | return rv; |
1729 | 0 | } |
1730 | | |
1731 | | /* |
1732 | | **************************** Radom Functions: ************************ |
1733 | | */ |
1734 | | |
1735 | | /* FC_SeedRandom mixes additional seed material into the token's random number |
1736 | | * generator. */ |
1737 | | CK_RV |
1738 | | FC_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, |
1739 | | CK_ULONG usSeedLen) |
1740 | 0 | { |
1741 | 0 | CK_RV crv; |
1742 | |
|
1743 | 0 | SFTK_FIPSFATALCHECK(); |
1744 | 0 | CHECK_FORK(); |
1745 | |
|
1746 | 0 | crv = NSC_SeedRandom(hSession, pSeed, usSeedLen); |
1747 | 0 | if (crv != CKR_OK) { |
1748 | 0 | sftk_fatalError = PR_TRUE; |
1749 | 0 | } |
1750 | 0 | return crv; |
1751 | 0 | } |
1752 | | |
1753 | | /* FC_GenerateRandom generates random data. */ |
1754 | | CK_RV |
1755 | | FC_GenerateRandom(CK_SESSION_HANDLE hSession, |
1756 | | CK_BYTE_PTR pRandomData, CK_ULONG ulRandomLen) |
1757 | 0 | { |
1758 | 0 | CK_RV crv; |
1759 | |
|
1760 | 0 | CHECK_FORK(); |
1761 | |
|
1762 | 0 | SFTK_FIPSFATALCHECK(); |
1763 | 0 | crv = NSC_GenerateRandom(hSession, pRandomData, ulRandomLen); |
1764 | 0 | if (crv != CKR_OK) { |
1765 | 0 | sftk_fatalError = PR_TRUE; |
1766 | 0 | if (sftk_audit_enabled) { |
1767 | 0 | char msg[128]; |
1768 | 0 | PR_snprintf(msg, sizeof msg, |
1769 | 0 | "C_GenerateRandom(hSession=0x%08lX, pRandomData=%p, " |
1770 | 0 | "ulRandomLen=%lu)=0x%08lX " |
1771 | 0 | "self-test: continuous RNG test failed", |
1772 | 0 | (PRUint32)hSession, pRandomData, |
1773 | 0 | (PRUint32)ulRandomLen, (PRUint32)crv); |
1774 | 0 | sftk_LogAuditMessage(NSS_AUDIT_ERROR, NSS_AUDIT_SELF_TEST, msg); |
1775 | 0 | } |
1776 | 0 | } |
1777 | 0 | return crv; |
1778 | 0 | } |
1779 | | |
1780 | | /* FC_GetFunctionStatus obtains an updated status of a function running |
1781 | | * in parallel with an application. */ |
1782 | | CK_RV |
1783 | | FC_GetFunctionStatus(CK_SESSION_HANDLE hSession) |
1784 | 0 | { |
1785 | 0 | SFTK_FIPSCHECK(); |
1786 | 0 | CHECK_FORK(); |
1787 | |
|
1788 | 0 | return NSC_GetFunctionStatus(hSession); |
1789 | 0 | } |
1790 | | |
1791 | | /* FC_CancelFunction cancels a function running in parallel */ |
1792 | | CK_RV |
1793 | | FC_CancelFunction(CK_SESSION_HANDLE hSession) |
1794 | 0 | { |
1795 | 0 | SFTK_FIPSCHECK(); |
1796 | 0 | CHECK_FORK(); |
1797 | |
|
1798 | 0 | return NSC_CancelFunction(hSession); |
1799 | 0 | } |
1800 | | |
1801 | | /* |
1802 | | **************************** Version 1.1 Functions: ************************ |
1803 | | */ |
1804 | | |
1805 | | /* FC_GetOperationState saves the state of the cryptographic |
1806 | | *operation in a session. */ |
1807 | | CK_RV |
1808 | | FC_GetOperationState(CK_SESSION_HANDLE hSession, |
1809 | | CK_BYTE_PTR pOperationState, CK_ULONG_PTR pulOperationStateLen) |
1810 | 0 | { |
1811 | 0 | SFTK_FIPSFATALCHECK(); |
1812 | 0 | CHECK_FORK(); |
1813 | |
|
1814 | 0 | return NSC_GetOperationState(hSession, pOperationState, pulOperationStateLen); |
1815 | 0 | } |
1816 | | |
1817 | | /* FC_SetOperationState restores the state of the cryptographic operation |
1818 | | * in a session. */ |
1819 | | CK_RV |
1820 | | FC_SetOperationState(CK_SESSION_HANDLE hSession, |
1821 | | CK_BYTE_PTR pOperationState, CK_ULONG ulOperationStateLen, |
1822 | | CK_OBJECT_HANDLE hEncryptionKey, CK_OBJECT_HANDLE hAuthenticationKey) |
1823 | 0 | { |
1824 | 0 | SFTK_FIPSFATALCHECK(); |
1825 | 0 | CHECK_FORK(); |
1826 | |
|
1827 | 0 | return NSC_SetOperationState(hSession, pOperationState, ulOperationStateLen, |
1828 | 0 | hEncryptionKey, hAuthenticationKey); |
1829 | 0 | } |
1830 | | |
1831 | | /* FC_FindObjectsFinal finishes a search for token and session objects. */ |
1832 | | CK_RV |
1833 | | FC_FindObjectsFinal(CK_SESSION_HANDLE hSession) |
1834 | 0 | { |
1835 | | /* let publically readable object be found */ |
1836 | 0 | SFTK_FIPSFATALCHECK(); |
1837 | 0 | CHECK_FORK(); |
1838 | |
|
1839 | 0 | return NSC_FindObjectsFinal(hSession); |
1840 | 0 | } |
1841 | | |
1842 | | /* Dual-function cryptographic operations */ |
1843 | | |
1844 | | /* FC_DigestEncryptUpdate continues a multiple-part digesting and encryption |
1845 | | * operation. */ |
1846 | | CK_RV |
1847 | | FC_DigestEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, |
1848 | | CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, |
1849 | | CK_ULONG_PTR pulEncryptedPartLen) |
1850 | 0 | { |
1851 | 0 | SFTK_FIPSCHECK(); |
1852 | 0 | CHECK_FORK(); |
1853 | |
|
1854 | 0 | return NSC_DigestEncryptUpdate(hSession, pPart, ulPartLen, pEncryptedPart, |
1855 | 0 | pulEncryptedPartLen); |
1856 | 0 | } |
1857 | | |
1858 | | /* FC_DecryptDigestUpdate continues a multiple-part decryption and digesting |
1859 | | * operation. */ |
1860 | | CK_RV |
1861 | | FC_DecryptDigestUpdate(CK_SESSION_HANDLE hSession, |
1862 | | CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, |
1863 | | CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen) |
1864 | 0 | { |
1865 | 0 | SFTK_FIPSCHECK(); |
1866 | 0 | CHECK_FORK(); |
1867 | |
|
1868 | 0 | return NSC_DecryptDigestUpdate(hSession, pEncryptedPart, ulEncryptedPartLen, |
1869 | 0 | pPart, pulPartLen); |
1870 | 0 | } |
1871 | | |
1872 | | /* FC_SignEncryptUpdate continues a multiple-part signing and encryption |
1873 | | * operation. */ |
1874 | | CK_RV |
1875 | | FC_SignEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, |
1876 | | CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, |
1877 | | CK_ULONG_PTR pulEncryptedPartLen) |
1878 | 0 | { |
1879 | 0 | SFTK_FIPSCHECK(); |
1880 | 0 | CHECK_FORK(); |
1881 | |
|
1882 | 0 | return NSC_SignEncryptUpdate(hSession, pPart, ulPartLen, pEncryptedPart, |
1883 | 0 | pulEncryptedPartLen); |
1884 | 0 | } |
1885 | | |
1886 | | /* FC_DecryptVerifyUpdate continues a multiple-part decryption and verify |
1887 | | * operation. */ |
1888 | | CK_RV |
1889 | | FC_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession, |
1890 | | CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, |
1891 | | CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen) |
1892 | 0 | { |
1893 | 0 | SFTK_FIPSCHECK(); |
1894 | 0 | CHECK_FORK(); |
1895 | |
|
1896 | 0 | return NSC_DecryptVerifyUpdate(hSession, pEncryptedData, ulEncryptedDataLen, |
1897 | 0 | pData, pulDataLen); |
1898 | 0 | } |
1899 | | |
1900 | | /* FC_DigestKey continues a multi-part message-digesting operation, |
1901 | | * by digesting the value of a secret key as part of the data already digested. |
1902 | | */ |
1903 | | CK_RV |
1904 | | FC_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey) |
1905 | 0 | { |
1906 | 0 | SFTK_FIPSCHECK(); |
1907 | 0 | CHECK_FORK(); |
1908 | |
|
1909 | 0 | rv = NSC_DigestKey(hSession, hKey); |
1910 | 0 | if (sftk_audit_enabled) { |
1911 | 0 | sftk_AuditDigestKey(hSession, hKey, rv); |
1912 | 0 | } |
1913 | 0 | return rv; |
1914 | 0 | } |
1915 | | |
1916 | | CK_RV |
1917 | | FC_WaitForSlotEvent(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, |
1918 | | CK_VOID_PTR pReserved) |
1919 | 0 | { |
1920 | 0 | CHECK_FORK(); |
1921 | |
|
1922 | 0 | return NSC_WaitForSlotEvent(flags, pSlot, pReserved); |
1923 | 0 | } |
1924 | | |
1925 | | CK_RV |
1926 | | FC_MessageEncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, |
1927 | | CK_OBJECT_HANDLE hKey) |
1928 | 0 | { |
1929 | 0 | SFTK_FIPSCHECK(); |
1930 | 0 | CHECK_FORK(); |
1931 | |
|
1932 | 0 | rv = NSC_MessageEncryptInit(hSession, pMechanism, hKey); |
1933 | 0 | if (sftk_audit_enabled) { |
1934 | 0 | sftk_AuditCryptInit("MessageEncrypt", hSession, pMechanism, hKey, rv); |
1935 | 0 | } |
1936 | 0 | return rv; |
1937 | 0 | } |
1938 | | |
1939 | | CK_RV |
1940 | | FC_EncryptMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, |
1941 | | CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData, |
1942 | | CK_ULONG ulAssociatedDataLen, CK_BYTE_PTR pPlaintext, |
1943 | | CK_ULONG ulPlaintextLen, CK_BYTE_PTR pCiphertext, |
1944 | | CK_ULONG_PTR pulCiphertextLen) |
1945 | 0 | { |
1946 | 0 | SFTK_FIPSCHECK(); |
1947 | 0 | CHECK_FORK(); |
1948 | 0 | return NSC_EncryptMessage(hSession, pParameter, ulParameterLen, |
1949 | 0 | pAssociatedData, ulAssociatedDataLen, |
1950 | 0 | pPlaintext, ulPlaintextLen, pCiphertext, |
1951 | 0 | pulCiphertextLen); |
1952 | 0 | } |
1953 | | |
1954 | | CK_RV |
1955 | | FC_EncryptMessageBegin(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, |
1956 | | CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData, |
1957 | | CK_ULONG ulAssociatedDataLen) |
1958 | 0 | { |
1959 | 0 | SFTK_FIPSCHECK(); |
1960 | 0 | CHECK_FORK(); |
1961 | 0 | return NSC_EncryptMessageBegin(hSession, pParameter, ulParameterLen, |
1962 | 0 | pAssociatedData, ulAssociatedDataLen); |
1963 | 0 | } |
1964 | | |
1965 | | CK_RV |
1966 | | FC_EncryptMessageNext(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, |
1967 | | CK_ULONG ulParameterLen, CK_BYTE_PTR pPlaintextPart, |
1968 | | CK_ULONG ulPlaintextPartLen, CK_BYTE_PTR pCiphertextPart, |
1969 | | CK_ULONG_PTR pulCiphertextPartLen, CK_FLAGS flags) |
1970 | 0 | { |
1971 | 0 | SFTK_FIPSCHECK(); |
1972 | 0 | CHECK_FORK(); |
1973 | 0 | return NSC_EncryptMessageNext(hSession, pParameter, ulParameterLen, |
1974 | 0 | pPlaintextPart, ulPlaintextPartLen, |
1975 | 0 | pCiphertextPart, pulCiphertextPartLen, flags); |
1976 | 0 | } |
1977 | | |
1978 | | CK_RV |
1979 | | FC_MessageEncryptFinal(CK_SESSION_HANDLE hSession) |
1980 | 0 | { |
1981 | 0 | SFTK_FIPSCHECK(); |
1982 | 0 | CHECK_FORK(); |
1983 | 0 | return NSC_MessageEncryptFinal(hSession); |
1984 | 0 | } |
1985 | | |
1986 | | CK_RV |
1987 | | FC_MessageDecryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, |
1988 | | CK_OBJECT_HANDLE hKey) |
1989 | 0 | { |
1990 | 0 | SFTK_FIPSCHECK(); |
1991 | 0 | CHECK_FORK(); |
1992 | |
|
1993 | 0 | rv = NSC_MessageDecryptInit(hSession, pMechanism, hKey); |
1994 | 0 | if (sftk_audit_enabled) { |
1995 | 0 | sftk_AuditCryptInit("MessageDecrypt", hSession, pMechanism, hKey, rv); |
1996 | 0 | } |
1997 | 0 | return rv; |
1998 | 0 | } |
1999 | | |
2000 | | CK_RV |
2001 | | FC_DecryptMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, |
2002 | | CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData, |
2003 | | CK_ULONG ulAssociatedDataLen, CK_BYTE_PTR pCiphertext, |
2004 | | CK_ULONG ulCiphertextLen, CK_BYTE_PTR pPlaintext, |
2005 | | CK_ULONG_PTR pulPlaintextLen) |
2006 | 0 | { |
2007 | 0 | SFTK_FIPSCHECK(); |
2008 | 0 | CHECK_FORK(); |
2009 | 0 | return NSC_DecryptMessage(hSession, pParameter, ulParameterLen, |
2010 | 0 | pAssociatedData, ulAssociatedDataLen, |
2011 | 0 | pCiphertext, ulCiphertextLen, pPlaintext, |
2012 | 0 | pulPlaintextLen); |
2013 | 0 | } |
2014 | | |
2015 | | CK_RV |
2016 | | FC_DecryptMessageBegin(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, |
2017 | | CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData, |
2018 | | CK_ULONG ulAssociatedDataLen) |
2019 | 0 | { |
2020 | 0 | SFTK_FIPSCHECK(); |
2021 | 0 | CHECK_FORK(); |
2022 | 0 | return NSC_DecryptMessageBegin(hSession, pParameter, ulParameterLen, |
2023 | 0 | pAssociatedData, ulAssociatedDataLen); |
2024 | 0 | } |
2025 | | |
2026 | | CK_RV |
2027 | | FC_DecryptMessageNext(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, |
2028 | | CK_ULONG ulParameterLen, CK_BYTE_PTR pCiphertextPart, |
2029 | | CK_ULONG ulCiphertextPartLen, CK_BYTE_PTR pPlaintextPart, |
2030 | | CK_ULONG_PTR pulPlaintextPartLen, CK_FLAGS flags) |
2031 | 0 | { |
2032 | 0 | SFTK_FIPSCHECK(); |
2033 | 0 | CHECK_FORK(); |
2034 | 0 | return NSC_DecryptMessageNext(hSession, pParameter, ulParameterLen, |
2035 | 0 | pCiphertextPart, ulCiphertextPartLen, |
2036 | 0 | pPlaintextPart, pulPlaintextPartLen, flags); |
2037 | 0 | } |
2038 | | |
2039 | | CK_RV |
2040 | | FC_MessageDecryptFinal(CK_SESSION_HANDLE hSession) |
2041 | 0 | { |
2042 | 0 | SFTK_FIPSCHECK(); |
2043 | 0 | CHECK_FORK(); |
2044 | 0 | return NSC_MessageDecryptFinal(hSession); |
2045 | 0 | } |
2046 | | |
2047 | | CK_RV |
2048 | | FC_MessageSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, |
2049 | | CK_OBJECT_HANDLE hKey) |
2050 | 0 | { |
2051 | 0 | SFTK_FIPSCHECK(); |
2052 | 0 | CHECK_FORK(); |
2053 | |
|
2054 | 0 | rv = NSC_MessageSignInit(hSession, pMechanism, hKey); |
2055 | 0 | if (sftk_audit_enabled) { |
2056 | 0 | sftk_AuditCryptInit("MessageSign", hSession, pMechanism, hKey, rv); |
2057 | 0 | } |
2058 | 0 | return rv; |
2059 | 0 | } |
2060 | | |
2061 | | CK_RV |
2062 | | FC_SignMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, |
2063 | | CK_ULONG ulParameterLen, CK_BYTE_PTR pData, CK_ULONG ulDataLen, |
2064 | | CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen) |
2065 | 0 | { |
2066 | 0 | SFTK_FIPSCHECK(); |
2067 | 0 | CHECK_FORK(); |
2068 | 0 | return NSC_SignMessage(hSession, pParameter, ulParameterLen, pData, |
2069 | 0 | ulDataLen, pSignature, pulSignatureLen); |
2070 | 0 | } |
2071 | | |
2072 | | CK_RV |
2073 | | FC_SignMessageBegin(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, |
2074 | | CK_ULONG ulParameterLen) |
2075 | 0 | { |
2076 | 0 | SFTK_FIPSCHECK(); |
2077 | 0 | CHECK_FORK(); |
2078 | 0 | return NSC_SignMessageBegin(hSession, pParameter, ulParameterLen); |
2079 | 0 | } |
2080 | | |
2081 | | CK_RV |
2082 | | FC_SignMessageNext(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, |
2083 | | CK_ULONG ulParameterLen, CK_BYTE_PTR pData, |
2084 | | CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, |
2085 | | CK_ULONG_PTR pulSignatureLen) |
2086 | 0 | { |
2087 | 0 | SFTK_FIPSCHECK(); |
2088 | 0 | CHECK_FORK(); |
2089 | 0 | return NSC_SignMessageNext(hSession, pParameter, ulParameterLen, pData, |
2090 | 0 | ulDataLen, pSignature, pulSignatureLen); |
2091 | 0 | } |
2092 | | |
2093 | | CK_RV |
2094 | | FC_MessageSignFinal(CK_SESSION_HANDLE hSession) |
2095 | 0 | { |
2096 | 0 | SFTK_FIPSCHECK(); |
2097 | 0 | CHECK_FORK(); |
2098 | 0 | return NSC_MessageSignFinal(hSession); |
2099 | 0 | } |
2100 | | |
2101 | | CK_RV |
2102 | | FC_MessageVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, |
2103 | | CK_OBJECT_HANDLE hKey) |
2104 | 0 | { |
2105 | 0 | SFTK_FIPSCHECK(); |
2106 | 0 | CHECK_FORK(); |
2107 | |
|
2108 | 0 | rv = NSC_MessageVerifyInit(hSession, pMechanism, hKey); |
2109 | 0 | if (sftk_audit_enabled) { |
2110 | 0 | sftk_AuditCryptInit("MessageVerify", hSession, pMechanism, hKey, rv); |
2111 | 0 | } |
2112 | 0 | return rv; |
2113 | 0 | } |
2114 | | |
2115 | | CK_RV |
2116 | | FC_VerifyMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, |
2117 | | CK_ULONG ulParameterLen, CK_BYTE_PTR pData, |
2118 | | CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, |
2119 | | CK_ULONG ulSignatureLen) |
2120 | 0 | { |
2121 | 0 | SFTK_FIPSCHECK(); |
2122 | 0 | CHECK_FORK(); |
2123 | 0 | return NSC_VerifyMessage(hSession, pParameter, ulParameterLen, pData, |
2124 | 0 | ulDataLen, pSignature, ulSignatureLen); |
2125 | 0 | } |
2126 | | |
2127 | | CK_RV |
2128 | | FC_VerifyMessageBegin(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, |
2129 | | CK_ULONG ulParameterLen) |
2130 | 0 | { |
2131 | 0 | SFTK_FIPSCHECK(); |
2132 | 0 | CHECK_FORK(); |
2133 | 0 | return NSC_VerifyMessageBegin(hSession, pParameter, ulParameterLen); |
2134 | 0 | } |
2135 | | |
2136 | | CK_RV |
2137 | | FC_VerifyMessageNext(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, |
2138 | | CK_ULONG ulParameterLen, CK_BYTE_PTR pData, |
2139 | | CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, |
2140 | | CK_ULONG ulSignatureLen) |
2141 | 0 | { |
2142 | 0 | SFTK_FIPSCHECK(); |
2143 | 0 | CHECK_FORK(); |
2144 | 0 | return NSC_VerifyMessageNext(hSession, pParameter, ulParameterLen, |
2145 | 0 | pData, ulDataLen, pSignature, ulSignatureLen); |
2146 | 0 | } |
2147 | | |
2148 | | CK_RV |
2149 | | FC_MessageVerifyFinal(CK_SESSION_HANDLE hSession) |
2150 | 0 | { |
2151 | 0 | SFTK_FIPSCHECK(); |
2152 | 0 | CHECK_FORK(); |
2153 | 0 | return NSC_MessageVerifyFinal(hSession); |
2154 | 0 | } |
2155 | | |
2156 | | CK_RV |
2157 | | FC_EncapsulateKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, |
2158 | | CK_OBJECT_HANDLE hPublicKey, CK_ATTRIBUTE_PTR pTemplate, |
2159 | | CK_ULONG ulAttributeCount, CK_BYTE_PTR pCiphertext, |
2160 | | CK_ULONG_PTR pulCiphertextLen, CK_OBJECT_HANDLE_PTR phKey) |
2161 | 0 | { |
2162 | 0 | CK_BBOOL *boolptr; |
2163 | |
|
2164 | 0 | SFTK_FIPSCHECK(); |
2165 | 0 | CHECK_FORK(); |
2166 | | |
2167 | | /* all secret keys must be sensitive, if the upper level code tries to say |
2168 | | * otherwise, reject it. */ |
2169 | 0 | boolptr = (CK_BBOOL *)fc_getAttribute(pTemplate, |
2170 | 0 | ulAttributeCount, CKA_SENSITIVE); |
2171 | 0 | if (boolptr != NULL) { |
2172 | 0 | if (!(*boolptr)) { |
2173 | 0 | return CKR_ATTRIBUTE_VALUE_INVALID; |
2174 | 0 | } |
2175 | 0 | } |
2176 | 0 | rv = NSC_EncapsulateKey(hSession, pMechanism, hPublicKey, |
2177 | 0 | pTemplate, ulAttributeCount, |
2178 | 0 | pCiphertext, pulCiphertextLen, phKey); |
2179 | 0 | if (sftk_audit_enabled) { |
2180 | 0 | sftk_AuditEncapsulateKey(hSession, pMechanism, hPublicKey, |
2181 | 0 | pTemplate, ulAttributeCount, |
2182 | 0 | pCiphertext, pulCiphertextLen, phKey, rv); |
2183 | 0 | } |
2184 | 0 | return rv; |
2185 | 0 | } |
2186 | | |
2187 | | CK_RV |
2188 | | FC_DecapsulateKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, |
2189 | | CK_OBJECT_HANDLE hPrivateKey, CK_ATTRIBUTE_PTR pTemplate, |
2190 | | CK_ULONG ulAttributeCount, CK_BYTE_PTR pCiphertext, |
2191 | | CK_ULONG ulCiphertextLen, CK_OBJECT_HANDLE_PTR phKey) |
2192 | 0 | { |
2193 | 0 | CK_BBOOL *boolptr; |
2194 | |
|
2195 | 0 | SFTK_FIPSCHECK(); |
2196 | 0 | CHECK_FORK(); |
2197 | | |
2198 | | /* all secret keys must be sensitive, if the upper level code tries to say |
2199 | | * otherwise, reject it. */ |
2200 | 0 | boolptr = (CK_BBOOL *)fc_getAttribute(pTemplate, |
2201 | 0 | ulAttributeCount, CKA_SENSITIVE); |
2202 | 0 | if (boolptr != NULL) { |
2203 | 0 | if (!(*boolptr)) { |
2204 | 0 | return CKR_ATTRIBUTE_VALUE_INVALID; |
2205 | 0 | } |
2206 | 0 | } |
2207 | 0 | rv = NSC_DecapsulateKey(hSession, pMechanism, hPrivateKey, |
2208 | 0 | pTemplate, ulAttributeCount, |
2209 | 0 | pCiphertext, ulCiphertextLen, phKey); |
2210 | 0 | if (sftk_audit_enabled) { |
2211 | 0 | sftk_AuditDecapsulateKey(hSession, pMechanism, hPrivateKey, |
2212 | 0 | pTemplate, ulAttributeCount, |
2213 | 0 | pCiphertext, ulCiphertextLen, phKey, rv); |
2214 | 0 | } |
2215 | 0 | return rv; |
2216 | 0 | } |
2217 | | |
2218 | | CK_RV |
2219 | | FC_GetSessionValidationFlags(CK_SESSION_HANDLE hSession, |
2220 | | CK_SESSION_VALIDATION_FLAGS_TYPE type, |
2221 | | CK_FLAGS_PTR pFlags) |
2222 | 0 | { |
2223 | 0 | SFTK_FIPSCHECK(); |
2224 | 0 | CHECK_FORK(); |
2225 | |
|
2226 | 0 | return NSC_GetSessionValidationFlags(hSession, type, pFlags); |
2227 | 0 | } |
2228 | | |
2229 | | CK_RV |
2230 | | FC_AsyncComplete(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pFunctionName, |
2231 | | CK_ASYNC_DATA_PTR pResult) |
2232 | 0 | { |
2233 | 0 | SFTK_FIPSCHECK(); |
2234 | 0 | CHECK_FORK(); |
2235 | |
|
2236 | 0 | return NSC_AsyncComplete(hSession, pFunctionName, pResult); |
2237 | 0 | } |
2238 | | |
2239 | | CK_RV |
2240 | | FC_AsyncGetID(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pFunctionName, |
2241 | | CK_ULONG_PTR pulID) |
2242 | 0 | { |
2243 | 0 | SFTK_FIPSCHECK(); |
2244 | 0 | CHECK_FORK(); |
2245 | |
|
2246 | 0 | return NSC_AsyncGetID(hSession, pFunctionName, pulID); |
2247 | 0 | } |
2248 | | |
2249 | | CK_RV |
2250 | | FC_AsyncJoin(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pFunctionName, |
2251 | | CK_ULONG ulID, CK_BYTE_PTR pData, CK_ULONG ulData) |
2252 | 0 | { |
2253 | 0 | SFTK_FIPSCHECK(); |
2254 | 0 | CHECK_FORK(); |
2255 | |
|
2256 | 0 | return FC_AsyncJoin(hSession, pFunctionName, ulID, pData, ulData); |
2257 | 0 | } |
2258 | | |
2259 | | CK_RV |
2260 | | FC_WrapKeyAuthenticated(CK_SESSION_HANDLE hSession, |
2261 | | CK_MECHANISM_PTR pMechanism, |
2262 | | CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey, |
2263 | | CK_BYTE_PTR pAssociatedData, |
2264 | | CK_ULONG ulAssociatedDataLen, |
2265 | | CK_BYTE_PTR pWrappedKey, CK_ULONG_PTR pulWrappedKeyLen) |
2266 | 0 | { |
2267 | 0 | SFTK_FIPSCHECK(); |
2268 | 0 | CHECK_FORK(); |
2269 | | |
2270 | | /* Before we support FC_WrapKeyAuthenticated, we'll have to add |
2271 | | * logging here, so just return CKR_FUNCTION_NOT_SUPPORTED until logging |
2272 | | * is added */ |
2273 | 0 | return CKR_FUNCTION_NOT_SUPPORTED; |
2274 | 0 | } |
2275 | | |
2276 | | CK_RV |
2277 | | FC_UnwrapKeyAuthenticated(CK_SESSION_HANDLE hSession, |
2278 | | CK_MECHANISM_PTR pMechanism, |
2279 | | CK_OBJECT_HANDLE hUnwrappingKey, |
2280 | | CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen, |
2281 | | CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, |
2282 | | CK_BYTE_PTR pAssociatedData, |
2283 | | CK_ULONG ulAssociatedDataLen, |
2284 | | CK_OBJECT_HANDLE_PTR phKey) |
2285 | 0 | { |
2286 | 0 | SFTK_FIPSCHECK(); |
2287 | 0 | CHECK_FORK(); |
2288 | | |
2289 | | /* Before we support FC_UnwrapKeyAuthenticated, we'll have to add |
2290 | | * logging here, so just return CKR_FUNCTION_NOT_SUPPORTED until logging |
2291 | | * is added */ |
2292 | 0 | return CKR_FUNCTION_NOT_SUPPORTED; |
2293 | 0 | } |