~ubuntu-branches/ubuntu/trusty/xulrunner/trusty

« back to all changes in this revision

Viewing changes to security/nss-fips/lib/softoken/fipstokn.c

  • Committer: Bazaar Package Importer
  • Author(s): Devid Antonio Filoni
  • Date: 2008-08-25 13:04:18 UTC
  • mfrom: (1.1.12 upstream)
  • Revision ID: james.westby@ubuntu.com-20080825130418-ck1i2ms384tzb9m0
Tags: 1.8.1.16+nobinonly-0ubuntu1
* New upstream release (taken from upstream CVS), LP: #254618.
* Fix MFSA 2008-35, MFSA 2008-34, MFSA 2008-33, MFSA 2008-32, MFSA 2008-31,
  MFSA 2008-30, MFSA 2008-29, MFSA 2008-28, MFSA 2008-27, MFSA 2008-25,
  MFSA 2008-24, MFSA 2008-23, MFSA 2008-22, MFSA 2008-21, MFSA 2008-26 also
  known as CVE-2008-2933, CVE-2008-2785, CVE-2008-2811, CVE-2008-2810,
  CVE-2008-2809, CVE-2008-2808, CVE-2008-2807, CVE-2008-2806, CVE-2008-2805,
  CVE-2008-2803, CVE-2008-2802, CVE-2008-2801, CVE-2008-2800, CVE-2008-2798.
* Drop 89_bz419350_attachment_306066 patch, merged upstream.
* Bump Standards-Version to 3.8.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ***** BEGIN LICENSE BLOCK *****
 
2
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 
3
 *
 
4
 * The contents of this file are subject to the Mozilla Public License Version
 
5
 * 1.1 (the "License"); you may not use this file except in compliance with
 
6
 * the License. You may obtain a copy of the License at
 
7
 * http://www.mozilla.org/MPL/
 
8
 *
 
9
 * Software distributed under the License is distributed on an "AS IS" basis,
 
10
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 
11
 * for the specific language governing rights and limitations under the
 
12
 * License.
 
13
 *
 
14
 * The Original Code is the Netscape security libraries.
 
15
 *
 
16
 * The Initial Developer of the Original Code is
 
17
 * Netscape Communications Corporation.
 
18
 * Portions created by the Initial Developer are Copyright (C) 1994-2000
 
19
 * the Initial Developer. All Rights Reserved.
 
20
 *
 
21
 * Contributor(s):
 
22
 *
 
23
 * Alternatively, the contents of this file may be used under the terms of
 
24
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 
25
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 
26
 * in which case the provisions of the GPL or the LGPL are applicable instead
 
27
 * of those above. If you wish to allow use of your version of this file only
 
28
 * under the terms of either the GPL or the LGPL, and not to allow others to
 
29
 * use your version of this file under the terms of the MPL, indicate your
 
30
 * decision by deleting the provisions above and replace them with the notice
 
31
 * and other provisions required by the GPL or the LGPL. If you do not delete
 
32
 * the provisions above, a recipient may use your version of this file under
 
33
 * the terms of any one of the MPL, the GPL or the LGPL.
 
34
 *
 
35
 * ***** END LICENSE BLOCK ***** */
 
36
/*
 
37
 * This file implements PKCS 11 on top of our existing security modules
 
38
 *
 
39
 * For more information about PKCS 11 See PKCS 11 Token Inteface Standard.
 
40
 *   This implementation has two slots:
 
41
 *      slot 1 is our generic crypto support. It does not require login
 
42
 *   (unless you've enabled FIPS). It supports Public Key ops, and all they
 
43
 *   bulk ciphers and hashes. It can also support Private Key ops for imported
 
44
 *   Private keys. It does not have any token storage.
 
45
 *      slot 2 is our private key support. It requires a login before use. It
 
46
 *   can store Private Keys and Certs as token objects. Currently only private
 
47
 *   keys and their associated Certificates are saved on the token.
 
48
 *
 
49
 *   In this implementation, session objects are only visible to the session
 
50
 *   that created or generated them.
 
51
 */
 
52
#include "seccomon.h"
 
53
#include "softoken.h"
 
54
#include "lowkeyi.h"
 
55
#include "pcert.h"
 
56
#include "pkcs11.h"
 
57
#include "pkcs11i.h"
 
58
#include "prenv.h"
 
59
#include "prprf.h"
 
60
 
 
61
#include <ctype.h>
 
62
 
 
63
#ifdef XP_UNIX
 
64
#define NSS_AUDIT_WITH_SYSLOG 1
 
65
#include <syslog.h>
 
66
#include <unistd.h>
 
67
#endif
 
68
 
 
69
#ifdef SOLARIS
 
70
#include <bsm/libbsm.h>
 
71
#define AUE_FIPS_AUDIT 34444
 
72
#endif
 
73
 
 
74
#ifdef LINUX
 
75
#include <pthread.h>
 
76
#include <dlfcn.h>
 
77
#define LIBAUDIT_NAME "libaudit.so.0"
 
78
#ifndef AUDIT_USER
 
79
#define AUDIT_USER 1005  /* message type: message from userspace */
 
80
#endif
 
81
static void *libaudit_handle;
 
82
static int (*audit_open_func)(void);
 
83
static void (*audit_close_func)(int fd);
 
84
static int (*audit_log_user_message_func)(int audit_fd, int type,
 
85
    const char *message, const char *hostname, const char *addr,
 
86
    const char *tty, int result);
 
87
static int (*audit_send_user_message_func)(int fd, int type,
 
88
    const char *message);
 
89
 
 
90
static pthread_once_t libaudit_once_control = PTHREAD_ONCE_INIT;
 
91
 
 
92
static void
 
93
libaudit_init(void)
 
94
{
 
95
    libaudit_handle = dlopen(LIBAUDIT_NAME, RTLD_LAZY);
 
96
    if (!libaudit_handle) {
 
97
        return;
 
98
    }
 
99
    audit_open_func = dlsym(libaudit_handle, "audit_open");
 
100
    audit_close_func = dlsym(libaudit_handle, "audit_close");
 
101
    /*
 
102
     * audit_send_user_message is the older function.
 
103
     * audit_log_user_message, if available, is preferred.
 
104
     */
 
105
    audit_log_user_message_func = dlsym(libaudit_handle,
 
106
                                        "audit_log_user_message");
 
107
    if (!audit_log_user_message_func) {
 
108
        audit_send_user_message_func = dlsym(libaudit_handle,
 
109
                                             "audit_send_user_message");
 
110
    }
 
111
    if (!audit_open_func || !audit_close_func ||
 
112
        (!audit_log_user_message_func && !audit_send_user_message_func)) {
 
113
        dlclose(libaudit_handle);
 
114
        libaudit_handle = NULL;
 
115
        audit_open_func = NULL;
 
116
        audit_close_func = NULL;
 
117
        audit_log_user_message_func = NULL;
 
118
        audit_send_user_message_func = NULL;
 
119
    }
 
120
}
 
121
#endif /* LINUX */
 
122
 
 
123
 
 
124
/*
 
125
 * ******************** Password Utilities *******************************
 
126
 */
 
127
static PRBool isLoggedIn = PR_FALSE;
 
128
PRBool sftk_fatalError = PR_FALSE;
 
129
 
 
130
/*
 
131
 * This function returns
 
132
 *   - CKR_PIN_INVALID if the password/PIN is not a legal UTF8 string
 
133
 *   - CKR_PIN_LEN_RANGE if the password/PIN is too short or does not
 
134
 *     consist of characters from three or more character classes.
 
135
 *   - CKR_OK otherwise
 
136
 *
 
137
 * The minimum password/PIN length is FIPS_MIN_PIN Unicode characters.
 
138
 * We define five character classes: digits (0-9), ASCII lowercase letters,
 
139
 * ASCII uppercase letters, ASCII non-alphanumeric characters (such as
 
140
 * space and punctuation marks), and non-ASCII characters.  If an ASCII
 
141
 * uppercase letter is the first character of the password/PIN, the
 
142
 * uppercase letter is not counted toward its character class.  Similarly,
 
143
 * if a digit is the last character of the password/PIN, the digit is not
 
144
 * counted toward its character class.
 
145
 *
 
146
 * Although NSC_SetPIN and NSC_InitPIN already do the maximum and minimum
 
147
 * password/PIN length checks, they check the length in bytes as opposed
 
148
 * to characters.  To meet the minimum password/PIN guessing probability
 
149
 * requirements in FIPS 140-2, we need to check the length in characters.
 
150
 */
 
151
static CK_RV sftk_newPinCheck(CK_CHAR_PTR pPin, CK_ULONG ulPinLen) {
 
152
    unsigned int i;
 
153
    int nchar = 0;      /* number of characters */
 
154
    int ntrail = 0;     /* number of trailing bytes to follow */
 
155
    int ndigit = 0;     /* number of decimal digits */
 
156
    int nlower = 0;     /* number of ASCII lowercase letters */
 
157
    int nupper = 0;     /* number of ASCII uppercase letters */
 
158
    int nnonalnum = 0;  /* number of ASCII non-alphanumeric characters */
 
159
    int nnonascii = 0;  /* number of non-ASCII characters */
 
160
    int nclass;         /* number of character classes */
 
161
 
 
162
    for (i = 0; i < ulPinLen; i++) {
 
163
        unsigned int byte = pPin[i];
 
164
 
 
165
        if (ntrail) {
 
166
            if ((byte & 0xc0) != 0x80) {
 
167
                /* illegal */
 
168
                nchar = -1;
 
169
                break;
 
170
            }
 
171
            if (--ntrail == 0) {
 
172
                nchar++;
 
173
                nnonascii++;
 
174
            }
 
175
            continue;
 
176
        }
 
177
        if ((byte & 0x80) == 0x00) {
 
178
            /* single-byte (ASCII) character */
 
179
            nchar++;
 
180
            if (isdigit(byte)) {
 
181
                if (i < ulPinLen - 1) {
 
182
                    ndigit++;
 
183
                }
 
184
            } else if (islower(byte)) {
 
185
                nlower++;
 
186
            } else if (isupper(byte)) {
 
187
                if (i > 0) {
 
188
                    nupper++;
 
189
                }
 
190
            } else {
 
191
                nnonalnum++;
 
192
            }
 
193
        } else if ((byte & 0xe0) == 0xc0) {
 
194
            /* leading byte of two-byte character */
 
195
            ntrail = 1;
 
196
        } else if ((byte & 0xf0) == 0xe0) {
 
197
            /* leading byte of three-byte character */
 
198
            ntrail = 2;
 
199
        } else if ((byte & 0xf8) == 0xf0) {
 
200
            /* leading byte of four-byte character */
 
201
            ntrail = 3;
 
202
        } else {
 
203
            /* illegal */
 
204
            nchar = -1;
 
205
            break;
 
206
        }
 
207
    }
 
208
    if (nchar == -1) {
 
209
        /* illegal UTF8 string */
 
210
        return CKR_PIN_INVALID;
 
211
    }
 
212
    if (nchar < FIPS_MIN_PIN) {
 
213
        return CKR_PIN_LEN_RANGE;
 
214
    }
 
215
    nclass = (ndigit != 0) + (nlower != 0) + (nupper != 0) +
 
216
             (nnonalnum != 0) + (nnonascii != 0);
 
217
    if (nclass < 3) {
 
218
        return CKR_PIN_LEN_RANGE;
 
219
    }
 
220
    return CKR_OK;
 
221
}
 
222
 
 
223
 
 
224
/* FIPS required checks before any useful cryptographic services */
 
225
static CK_RV sftk_fipsCheck(void) {
 
226
    if (sftk_fatalError) 
 
227
        return CKR_DEVICE_ERROR;
 
228
    if (!isLoggedIn) 
 
229
        return CKR_USER_NOT_LOGGED_IN;
 
230
    return CKR_OK;
 
231
}
 
232
 
 
233
 
 
234
#define SFTK_FIPSCHECK() \
 
235
    CK_RV rv; \
 
236
    if ((rv = sftk_fipsCheck()) != CKR_OK) return rv;
 
237
 
 
238
#define SFTK_FIPSFATALCHECK() \
 
239
    if (sftk_fatalError) return CKR_DEVICE_ERROR;
 
240
 
 
241
 
 
242
/* grab an attribute out of a raw template */
 
243
void *
 
244
fc_getAttribute(CK_ATTRIBUTE_PTR pTemplate, 
 
245
                                CK_ULONG ulCount, CK_ATTRIBUTE_TYPE type)
 
246
{
 
247
    int i;
 
248
 
 
249
    for (i=0; i < (int) ulCount; i++) {
 
250
        if (pTemplate[i].type == type) {
 
251
            return pTemplate[i].pValue;
 
252
        }
 
253
    }
 
254
    return NULL;
 
255
}
 
256
 
 
257
 
 
258
#define __PASTE(x,y)    x##y
 
259
 
 
260
/* ------------- forward declare all the NSC_ functions ------------- */
 
261
#undef CK_NEED_ARG_LIST
 
262
#undef CK_PKCS11_FUNCTION_INFO
 
263
 
 
264
#define CK_PKCS11_FUNCTION_INFO(name) CK_RV __PASTE(NS,name)
 
265
#define CK_NEED_ARG_LIST 1
 
266
 
 
267
#include "pkcs11f.h"
 
268
 
 
269
/* ------------- forward declare all the FIPS functions ------------- */
 
270
#undef CK_NEED_ARG_LIST
 
271
#undef CK_PKCS11_FUNCTION_INFO
 
272
 
 
273
#define CK_PKCS11_FUNCTION_INFO(name) CK_RV __PASTE(F,name)
 
274
#define CK_NEED_ARG_LIST 1
 
275
 
 
276
#include "pkcs11f.h"
 
277
 
 
278
/* ------------- build the CK_CRYPTO_TABLE ------------------------- */
 
279
static CK_FUNCTION_LIST sftk_fipsTable = {
 
280
    { 1, 10 },
 
281
 
 
282
#undef CK_NEED_ARG_LIST
 
283
#undef CK_PKCS11_FUNCTION_INFO
 
284
 
 
285
#define CK_PKCS11_FUNCTION_INFO(name) __PASTE(F,name),
 
286
 
 
287
 
 
288
#include "pkcs11f.h"
 
289
 
 
290
};
 
291
 
 
292
#undef CK_NEED_ARG_LIST
 
293
#undef CK_PKCS11_FUNCTION_INFO
 
294
 
 
295
 
 
296
#undef __PASTE
 
297
 
 
298
/* CKO_NOT_A_KEY can be any object class that's not a key object. */
 
299
#define CKO_NOT_A_KEY CKO_DATA
 
300
 
 
301
#define SFTK_IS_KEY_OBJECT(objClass) \
 
302
    (((objClass) == CKO_PUBLIC_KEY) || \
 
303
    ((objClass) == CKO_PRIVATE_KEY) || \
 
304
    ((objClass) == CKO_SECRET_KEY))
 
305
 
 
306
#define SFTK_IS_NONPUBLIC_KEY_OBJECT(objClass) \
 
307
    (((objClass) == CKO_PRIVATE_KEY) || ((objClass) == CKO_SECRET_KEY))
 
308
 
 
309
static CK_RV
 
310
sftk_get_object_class_and_fipsCheck(CK_SESSION_HANDLE hSession,
 
311
    CK_OBJECT_HANDLE hObject, CK_OBJECT_CLASS *pObjClass)
 
312
{
 
313
    CK_RV rv;
 
314
    CK_ATTRIBUTE class; 
 
315
    class.type = CKA_CLASS;
 
316
    class.pValue = pObjClass;
 
317
    class.ulValueLen = sizeof(*pObjClass);
 
318
    rv = NSC_GetAttributeValue(hSession, hObject, &class, 1);
 
319
    if ((rv == CKR_OK) && SFTK_IS_NONPUBLIC_KEY_OBJECT(*pObjClass)) {
 
320
        rv = sftk_fipsCheck();
 
321
    }
 
322
    return rv;
 
323
}
 
324
 
 
325
/**********************************************************************
 
326
 *
 
327
 *     FIPS 140 auditable event logging
 
328
 *
 
329
 **********************************************************************/
 
330
 
 
331
PRBool sftk_audit_enabled = PR_FALSE;
 
332
 
 
333
/*
 
334
 * Each audit record must have the following information:
 
335
 * - Date and time of the event
 
336
 * - Type of event
 
337
 * - user (subject) identity
 
338
 * - outcome (success or failure) of the event
 
339
 * - process ID
 
340
 * - name (ID) of the object
 
341
 * - for changes to data (except for authentication data and CSPs), the new
 
342
 *   and old values of the data
 
343
 * - for authentication attempts, the origin of the attempt (e.g., terminal
 
344
 *   identifier)
 
345
 * - for assuming a role, the type of role, and the location of the request
 
346
 */
 
347
void
 
348
sftk_LogAuditMessage(NSSAuditSeverity severity, const char *msg)
 
349
{
 
350
#ifdef NSS_AUDIT_WITH_SYSLOG
 
351
    int level;
 
352
 
 
353
    switch (severity) {
 
354
    case NSS_AUDIT_ERROR:
 
355
        level = LOG_ERR;
 
356
        break;
 
357
    case NSS_AUDIT_WARNING:
 
358
        level = LOG_WARNING;
 
359
        break;
 
360
    default:
 
361
        level = LOG_INFO;
 
362
        break;
 
363
    }
 
364
    /* timestamp is provided by syslog in the message header */
 
365
    syslog(level | LOG_USER /* facility */,
 
366
           "NSS " SOFTOKEN_LIB_NAME "[pid=%d uid=%d]: %s",
 
367
           (int)getpid(), (int)getuid(), msg);
 
368
#ifdef LINUX
 
369
    if (pthread_once(&libaudit_once_control, libaudit_init) != 0) {
 
370
        return;
 
371
    }
 
372
    if (libaudit_handle) {
 
373
        int audit_fd;
 
374
        int result = (severity != NSS_AUDIT_ERROR); /* 1=success; 0=failed */
 
375
        char *message = PR_smprintf("NSS " SOFTOKEN_LIB_NAME ": %s", msg);
 
376
        if (!message) {
 
377
            return;
 
378
        }
 
379
        audit_fd = audit_open_func();
 
380
        if (audit_fd < 0) {
 
381
            PR_smprintf_free(message);
 
382
            return;
 
383
        }
 
384
        if (audit_log_user_message_func) {
 
385
            audit_log_user_message_func(audit_fd, AUDIT_USER, message,
 
386
                                        NULL, NULL, NULL, result);
 
387
        } else {
 
388
            audit_send_user_message_func(audit_fd, AUDIT_USER, message);
 
389
        }
 
390
        audit_close_func(audit_fd);
 
391
        PR_smprintf_free(message);
 
392
    }
 
393
#endif /* LINUX */
 
394
#ifdef SOLARIS
 
395
    {
 
396
        int rd;
 
397
        char *message = PR_smprintf("NSS " SOFTOKEN_LIB_NAME ": %s", msg);
 
398
 
 
399
        if (!message) {
 
400
            return;
 
401
        }
 
402
 
 
403
        /* open the record descriptor */
 
404
        if ((rd = au_open()) == -1) {
 
405
            PR_smprintf_free(message);
 
406
            return;
 
407
        }
 
408
 
 
409
        /* write the audit tokens to the audit record */
 
410
        if (au_write(rd, au_to_text(message))) {
 
411
            (void)au_close(rd, AU_TO_NO_WRITE, AUE_FIPS_AUDIT);
 
412
            PR_smprintf_free(message);
 
413
            return;
 
414
        }
 
415
 
 
416
        /* close the record and send it to the audit trail */
 
417
        (void)au_close(rd, AU_TO_WRITE, AUE_FIPS_AUDIT);
 
418
 
 
419
        PR_smprintf_free(message);
 
420
    }
 
421
#endif /* SOLARIS */
 
422
#else
 
423
    /* do nothing */
 
424
#endif
 
425
}
 
426
 
 
427
 
 
428
/**********************************************************************
 
429
 *
 
430
 *     Start of PKCS 11 functions 
 
431
 *
 
432
 **********************************************************************/
 
433
/* return the function list */
 
434
CK_RV FC_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList) {
 
435
    *pFunctionList = &sftk_fipsTable;
 
436
    return CKR_OK;
 
437
}
 
438
 
 
439
/* sigh global so pkcs11 can read it */
 
440
PRBool nsf_init = PR_FALSE;
 
441
 
 
442
/* FC_Initialize initializes the PKCS #11 library. */
 
443
CK_RV FC_Initialize(CK_VOID_PTR pReserved) {
 
444
    const char *envp;
 
445
    CK_RV crv;
 
446
 
 
447
    if (nsf_init) {
 
448
        return CKR_CRYPTOKI_ALREADY_INITIALIZED;
 
449
    }
 
450
 
 
451
    if ((envp = PR_GetEnv("NSS_ENABLE_AUDIT")) != NULL) {
 
452
        sftk_audit_enabled = (atoi(envp) == 1);
 
453
    }
 
454
 
 
455
    crv = nsc_CommonInitialize(pReserved, PR_TRUE);
 
456
 
 
457
    /* not an 'else' rv can be set by either SFTK_LowInit or SFTK_SlotInit*/
 
458
    if (crv != CKR_OK) {
 
459
        sftk_fatalError = PR_TRUE;
 
460
        return crv;
 
461
    }
 
462
 
 
463
    sftk_fatalError = PR_FALSE; /* any error has been reset */
 
464
 
 
465
    crv = sftk_fipsPowerUpSelfTest();
 
466
    if (crv != CKR_OK) {
 
467
        nsc_CommonFinalize(NULL, PR_TRUE);
 
468
        sftk_fatalError = PR_TRUE;
 
469
        if (sftk_audit_enabled) {
 
470
            char msg[128];
 
471
            PR_snprintf(msg,sizeof msg,
 
472
                        "C_Initialize()=0x%08lX "
 
473
                        "power-up self-tests failed",
 
474
                        (PRUint32)crv);
 
475
            sftk_LogAuditMessage(NSS_AUDIT_ERROR, msg);
 
476
        }
 
477
        return crv;
 
478
    }
 
479
    nsf_init = PR_TRUE;
 
480
 
 
481
    return CKR_OK;
 
482
}
 
483
 
 
484
/*FC_Finalize indicates that an application is done with the PKCS #11 library.*/
 
485
CK_RV FC_Finalize (CK_VOID_PTR pReserved) {
 
486
   CK_RV crv;
 
487
   if (!nsf_init) {
 
488
      return CKR_OK;
 
489
   }
 
490
   crv = nsc_CommonFinalize (pReserved, PR_TRUE);
 
491
   nsf_init = (PRBool) !(crv == CKR_OK);
 
492
   return crv;
 
493
}
 
494
 
 
495
 
 
496
/* FC_GetInfo returns general information about PKCS #11. */
 
497
CK_RV  FC_GetInfo(CK_INFO_PTR pInfo) {
 
498
    return NSC_GetInfo(pInfo);
 
499
}
 
500
 
 
501
/* FC_GetSlotList obtains a list of slots in the system. */
 
502
CK_RV FC_GetSlotList(CK_BBOOL tokenPresent,
 
503
                        CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount) {
 
504
    return nsc_CommonGetSlotList(tokenPresent,pSlotList,pulCount,
 
505
                                                         NSC_FIPS_MODULE);
 
506
}
 
507
        
 
508
/* FC_GetSlotInfo obtains information about a particular slot in the system. */
 
509
CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
 
510
    return NSC_GetSlotInfo(slotID,pInfo);
 
511
}
 
512
 
 
513
 
 
514
/*FC_GetTokenInfo obtains information about a particular token in the system.*/
 
515
 CK_RV FC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo) {
 
516
    CK_RV crv;
 
517
 
 
518
    crv = NSC_GetTokenInfo(slotID,pInfo);
 
519
    if (crv == CKR_OK) 
 
520
       pInfo->flags |= CKF_LOGIN_REQUIRED;
 
521
    return crv;
 
522
 
 
523
}
 
524
 
 
525
 
 
526
 
 
527
/*FC_GetMechanismList obtains a list of mechanism types supported by a token.*/
 
528
 CK_RV FC_GetMechanismList(CK_SLOT_ID slotID,
 
529
        CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pusCount) {
 
530
    SFTK_FIPSFATALCHECK();
 
531
    if (slotID == FIPS_SLOT_ID) slotID = NETSCAPE_SLOT_ID;
 
532
    /* FIPS Slot supports all functions */
 
533
    return NSC_GetMechanismList(slotID,pMechanismList,pusCount);
 
534
}
 
535
 
 
536
 
 
537
/* FC_GetMechanismInfo obtains information about a particular mechanism 
 
538
 * possibly supported by a token. */
 
539
 CK_RV FC_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type,
 
540
                                        CK_MECHANISM_INFO_PTR pInfo) {
 
541
    SFTK_FIPSFATALCHECK();
 
542
    if (slotID == FIPS_SLOT_ID) slotID = NETSCAPE_SLOT_ID;
 
543
    /* FIPS Slot supports all functions */
 
544
    return NSC_GetMechanismInfo(slotID,type,pInfo);
 
545
}
 
546
 
 
547
 
 
548
/* FC_InitToken initializes a token. */
 
549
 CK_RV FC_InitToken(CK_SLOT_ID slotID,CK_CHAR_PTR pPin,
 
550
                                CK_ULONG usPinLen,CK_CHAR_PTR pLabel) {
 
551
    CK_RV crv;
 
552
 
 
553
    crv = NSC_InitToken(slotID,pPin,usPinLen,pLabel);
 
554
    if (sftk_audit_enabled) {
 
555
        char msg[128];
 
556
        NSSAuditSeverity severity = (crv == CKR_OK) ?
 
557
                NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
 
558
        /* pLabel points to a 32-byte label, which is not null-terminated */
 
559
        PR_snprintf(msg,sizeof msg,
 
560
                "C_InitToken(slotID=%lu, pLabel=\"%.32s\")=0x%08lX",
 
561
                (PRUint32)slotID,pLabel,(PRUint32)crv);
 
562
        sftk_LogAuditMessage(severity, msg);
 
563
    }
 
564
    return crv;
 
565
}
 
566
 
 
567
 
 
568
/* FC_InitPIN initializes the normal user's PIN. */
 
569
 CK_RV FC_InitPIN(CK_SESSION_HANDLE hSession,
 
570
                                        CK_CHAR_PTR pPin, CK_ULONG ulPinLen) {
 
571
    CK_RV rv;
 
572
    if (sftk_fatalError) return CKR_DEVICE_ERROR;
 
573
    if ((rv = sftk_newPinCheck(pPin,ulPinLen)) == CKR_OK) {
 
574
        rv = NSC_InitPIN(hSession,pPin,ulPinLen);
 
575
    }
 
576
    if (sftk_audit_enabled) {
 
577
        char msg[128];
 
578
        NSSAuditSeverity severity = (rv == CKR_OK) ?
 
579
                NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
 
580
        PR_snprintf(msg,sizeof msg,
 
581
                "C_InitPIN(hSession=0x%08lX)=0x%08lX",
 
582
                (PRUint32)hSession,(PRUint32)rv);
 
583
        sftk_LogAuditMessage(severity, msg);
 
584
    }
 
585
    return rv;
 
586
}
 
587
 
 
588
 
 
589
/* FC_SetPIN modifies the PIN of user that is currently logged in. */
 
590
/* NOTE: This is only valid for the PRIVATE_KEY_SLOT */
 
591
 CK_RV FC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin,
 
592
    CK_ULONG usOldLen, CK_CHAR_PTR pNewPin, CK_ULONG usNewLen) {
 
593
    CK_RV rv;
 
594
    if ((rv = sftk_fipsCheck()) == CKR_OK &&
 
595
        (rv = sftk_newPinCheck(pNewPin,usNewLen)) == CKR_OK) {
 
596
        rv = NSC_SetPIN(hSession,pOldPin,usOldLen,pNewPin,usNewLen);
 
597
    }
 
598
    if (sftk_audit_enabled) {
 
599
        char msg[128];
 
600
        NSSAuditSeverity severity = (rv == CKR_OK) ?
 
601
                NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
 
602
        PR_snprintf(msg,sizeof msg,
 
603
                "C_SetPIN(hSession=0x%08lX)=0x%08lX",
 
604
                (PRUint32)hSession,(PRUint32)rv);
 
605
        sftk_LogAuditMessage(severity, msg);
 
606
    }
 
607
    return rv;
 
608
}
 
609
 
 
610
/* FC_OpenSession opens a session between an application and a token. */
 
611
 CK_RV FC_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags,
 
612
   CK_VOID_PTR pApplication,CK_NOTIFY Notify,CK_SESSION_HANDLE_PTR phSession) {
 
613
    SFTK_FIPSFATALCHECK();
 
614
    return NSC_OpenSession(slotID,flags,pApplication,Notify,phSession);
 
615
}
 
616
 
 
617
 
 
618
/* FC_CloseSession closes a session between an application and a token. */
 
619
 CK_RV FC_CloseSession(CK_SESSION_HANDLE hSession) {
 
620
    return NSC_CloseSession(hSession);
 
621
}
 
622
 
 
623
 
 
624
/* FC_CloseAllSessions closes all sessions with a token. */
 
625
 CK_RV FC_CloseAllSessions (CK_SLOT_ID slotID) {
 
626
    return NSC_CloseAllSessions (slotID);
 
627
}
 
628
 
 
629
 
 
630
/* FC_GetSessionInfo obtains information about the session. */
 
631
 CK_RV FC_GetSessionInfo(CK_SESSION_HANDLE hSession,
 
632
                                                CK_SESSION_INFO_PTR pInfo) {
 
633
    CK_RV rv;
 
634
    SFTK_FIPSFATALCHECK();
 
635
 
 
636
    rv = NSC_GetSessionInfo(hSession,pInfo);
 
637
    if (rv == CKR_OK) {
 
638
        if ((isLoggedIn) && (pInfo->state == CKS_RO_PUBLIC_SESSION)) {
 
639
                pInfo->state = CKS_RO_USER_FUNCTIONS;
 
640
        }
 
641
        if ((isLoggedIn) && (pInfo->state == CKS_RW_PUBLIC_SESSION)) {
 
642
                pInfo->state = CKS_RW_USER_FUNCTIONS;
 
643
        }
 
644
    }
 
645
    return rv;
 
646
}
 
647
 
 
648
/* FC_Login logs a user into a token. */
 
649
 CK_RV FC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
 
650
                                    CK_CHAR_PTR pPin, CK_ULONG usPinLen) {
 
651
    CK_RV rv;
 
652
    PRBool successful;
 
653
    if (sftk_fatalError) return CKR_DEVICE_ERROR;
 
654
    rv = NSC_Login(hSession,userType,pPin,usPinLen);
 
655
    successful = (rv == CKR_OK) || (rv == CKR_USER_ALREADY_LOGGED_IN);
 
656
    if (successful)
 
657
        isLoggedIn = PR_TRUE;
 
658
    if (sftk_audit_enabled) {
 
659
        char msg[128];
 
660
        NSSAuditSeverity severity;
 
661
        severity = successful ? NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
 
662
        PR_snprintf(msg,sizeof msg,
 
663
                    "C_Login(hSession=0x%08lX, userType=%lu)=0x%08lX",
 
664
                    (PRUint32)hSession,(PRUint32)userType,(PRUint32)rv);
 
665
        sftk_LogAuditMessage(severity, msg);
 
666
    }
 
667
    return rv;
 
668
}
 
669
 
 
670
/* FC_Logout logs a user out from a token. */
 
671
 CK_RV FC_Logout(CK_SESSION_HANDLE hSession) {
 
672
    CK_RV rv;
 
673
    if ((rv = sftk_fipsCheck()) == CKR_OK) {
 
674
        rv = NSC_Logout(hSession);
 
675
        isLoggedIn = PR_FALSE;
 
676
    }
 
677
    if (sftk_audit_enabled) {
 
678
        char msg[128];
 
679
        NSSAuditSeverity severity = (rv == CKR_OK) ?
 
680
                NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
 
681
        PR_snprintf(msg,sizeof msg,
 
682
                    "C_Logout(hSession=0x%08lX)=0x%08lX",
 
683
                    (PRUint32)hSession,(PRUint32)rv);
 
684
        sftk_LogAuditMessage(severity, msg);
 
685
    }
 
686
    return rv;
 
687
}
 
688
 
 
689
 
 
690
/* FC_CreateObject creates a new object. */
 
691
 CK_RV FC_CreateObject(CK_SESSION_HANDLE hSession,
 
692
                CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, 
 
693
                                        CK_OBJECT_HANDLE_PTR phObject) {
 
694
    CK_OBJECT_CLASS * classptr;
 
695
    SFTK_FIPSCHECK();
 
696
    classptr = (CK_OBJECT_CLASS *)fc_getAttribute(pTemplate,ulCount,CKA_CLASS);
 
697
    if (classptr == NULL) return CKR_TEMPLATE_INCOMPLETE;
 
698
 
 
699
    /* FIPS can't create keys from raw key material */
 
700
    if (SFTK_IS_NONPUBLIC_KEY_OBJECT(*classptr)) {
 
701
        rv = CKR_ATTRIBUTE_VALUE_INVALID;
 
702
    } else {
 
703
        rv = NSC_CreateObject(hSession,pTemplate,ulCount,phObject);
 
704
    }
 
705
    if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(*classptr)) {
 
706
        sftk_AuditCreateObject(hSession,pTemplate,ulCount,phObject,rv);
 
707
    }
 
708
    return rv;
 
709
}
 
710
 
 
711
 
 
712
 
 
713
 
 
714
 
 
715
/* FC_CopyObject copies an object, creating a new object for the copy. */
 
716
 CK_RV FC_CopyObject(CK_SESSION_HANDLE hSession,
 
717
       CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
 
718
                                        CK_OBJECT_HANDLE_PTR phNewObject) {
 
719
    CK_RV rv;
 
720
    CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY;
 
721
    SFTK_FIPSFATALCHECK();
 
722
    rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass);
 
723
    if (rv == CKR_OK) {
 
724
        rv = NSC_CopyObject(hSession,hObject,pTemplate,ulCount,phNewObject);
 
725
    }
 
726
    if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) {
 
727
        sftk_AuditCopyObject(hSession,
 
728
            hObject,pTemplate,ulCount,phNewObject,rv);
 
729
    }
 
730
    return rv;
 
731
}
 
732
 
 
733
 
 
734
/* FC_DestroyObject destroys an object. */
 
735
 CK_RV FC_DestroyObject(CK_SESSION_HANDLE hSession,
 
736
                                                CK_OBJECT_HANDLE hObject) {
 
737
    CK_RV rv;
 
738
    CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY;
 
739
    SFTK_FIPSFATALCHECK();
 
740
    rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass);
 
741
    if (rv == CKR_OK) {
 
742
        rv = NSC_DestroyObject(hSession,hObject);
 
743
    }
 
744
    if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) {
 
745
        sftk_AuditDestroyObject(hSession,hObject,rv);
 
746
    }
 
747
    return rv;
 
748
}
 
749
 
 
750
 
 
751
/* FC_GetObjectSize gets the size of an object in bytes. */
 
752
 CK_RV FC_GetObjectSize(CK_SESSION_HANDLE hSession,
 
753
                        CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize) {
 
754
    CK_RV rv;
 
755
    CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY;
 
756
    SFTK_FIPSFATALCHECK();
 
757
    rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass);
 
758
    if (rv == CKR_OK) {
 
759
        rv = NSC_GetObjectSize(hSession, hObject, pulSize);
 
760
    }
 
761
    if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) {
 
762
        sftk_AuditGetObjectSize(hSession, hObject, pulSize, rv);
 
763
    }
 
764
    return rv;
 
765
}
 
766
 
 
767
 
 
768
/* FC_GetAttributeValue obtains the value of one or more object attributes. */
 
769
 CK_RV FC_GetAttributeValue(CK_SESSION_HANDLE hSession,
 
770
 CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount) {
 
771
    CK_RV rv;
 
772
    CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY;
 
773
    SFTK_FIPSFATALCHECK();
 
774
    rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass);
 
775
    if (rv == CKR_OK) {
 
776
        rv = NSC_GetAttributeValue(hSession,hObject,pTemplate,ulCount);
 
777
    }
 
778
    if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) {
 
779
        sftk_AuditGetAttributeValue(hSession,hObject,pTemplate,ulCount,rv);
 
780
    }
 
781
    return rv;
 
782
}
 
783
 
 
784
 
 
785
/* FC_SetAttributeValue modifies the value of one or more object attributes */
 
786
 CK_RV FC_SetAttributeValue (CK_SESSION_HANDLE hSession,
 
787
 CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount) {
 
788
    CK_RV rv;
 
789
    CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY;
 
790
    SFTK_FIPSFATALCHECK();
 
791
    rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass);
 
792
    if (rv == CKR_OK) {
 
793
        rv = NSC_SetAttributeValue(hSession,hObject,pTemplate,ulCount);
 
794
    }
 
795
    if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) {
 
796
        sftk_AuditSetAttributeValue(hSession,hObject,pTemplate,ulCount,rv);
 
797
    }
 
798
    return rv;
 
799
}
 
800
 
 
801
 
 
802
 
 
803
/* FC_FindObjectsInit initializes a search for token and session objects 
 
804
 * that match a template. */
 
805
 CK_RV FC_FindObjectsInit(CK_SESSION_HANDLE hSession,
 
806
                        CK_ATTRIBUTE_PTR pTemplate,CK_ULONG usCount) {
 
807
    /* let publically readable object be found */
 
808
    unsigned int i;
 
809
    CK_RV rv;
 
810
    PRBool needLogin = PR_FALSE;
 
811
 
 
812
    SFTK_FIPSFATALCHECK();
 
813
 
 
814
    for (i=0; i < usCount; i++) {
 
815
        CK_OBJECT_CLASS class;
 
816
        if (pTemplate[i].type != CKA_CLASS) {
 
817
            continue;
 
818
        }
 
819
        if (pTemplate[i].ulValueLen != sizeof(CK_OBJECT_CLASS)) {
 
820
            continue;
 
821
        }
 
822
        if (pTemplate[i].pValue == NULL) {
 
823
            continue;
 
824
        }
 
825
        class = *(CK_OBJECT_CLASS *)pTemplate[i].pValue;
 
826
        if ((class == CKO_PRIVATE_KEY) || (class == CKO_SECRET_KEY)) {
 
827
            needLogin = PR_TRUE;
 
828
            break;
 
829
        }
 
830
    }
 
831
    if (needLogin) {
 
832
        if ((rv = sftk_fipsCheck()) != CKR_OK) return rv;
 
833
    }
 
834
    return NSC_FindObjectsInit(hSession,pTemplate,usCount);
 
835
}
 
836
 
 
837
 
 
838
/* FC_FindObjects continues a search for token and session objects 
 
839
 * that match a template, obtaining additional object handles. */
 
840
 CK_RV FC_FindObjects(CK_SESSION_HANDLE hSession,
 
841
    CK_OBJECT_HANDLE_PTR phObject,CK_ULONG usMaxObjectCount,
 
842
                                        CK_ULONG_PTR pusObjectCount) {
 
843
    /* let publically readable object be found */
 
844
    SFTK_FIPSFATALCHECK();
 
845
    return NSC_FindObjects(hSession,phObject,usMaxObjectCount,
 
846
                                                        pusObjectCount);
 
847
}
 
848
 
 
849
 
 
850
/*
 
851
 ************** Crypto Functions:     Encrypt ************************
 
852
 */
 
853
 
 
854
/* FC_EncryptInit initializes an encryption operation. */
 
855
 CK_RV FC_EncryptInit(CK_SESSION_HANDLE hSession,
 
856
                 CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) {
 
857
    SFTK_FIPSCHECK();
 
858
    rv = NSC_EncryptInit(hSession,pMechanism,hKey);
 
859
    if (sftk_audit_enabled) {
 
860
        sftk_AuditCryptInit("Encrypt",hSession,pMechanism,hKey,rv);
 
861
    }
 
862
    return rv;
 
863
}
 
864
 
 
865
/* FC_Encrypt encrypts single-part data. */
 
866
 CK_RV FC_Encrypt (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
 
867
                CK_ULONG usDataLen, CK_BYTE_PTR pEncryptedData,
 
868
                                         CK_ULONG_PTR pusEncryptedDataLen) {
 
869
    SFTK_FIPSCHECK();
 
870
    return NSC_Encrypt(hSession,pData,usDataLen,pEncryptedData,
 
871
                                                        pusEncryptedDataLen);
 
872
}
 
873
 
 
874
 
 
875
/* FC_EncryptUpdate continues a multiple-part encryption operation. */
 
876
 CK_RV FC_EncryptUpdate(CK_SESSION_HANDLE hSession,
 
877
    CK_BYTE_PTR pPart, CK_ULONG usPartLen, CK_BYTE_PTR pEncryptedPart,  
 
878
                                        CK_ULONG_PTR pusEncryptedPartLen) {
 
879
    SFTK_FIPSCHECK();
 
880
    return NSC_EncryptUpdate(hSession,pPart,usPartLen,pEncryptedPart,
 
881
                                                pusEncryptedPartLen);
 
882
}
 
883
 
 
884
 
 
885
/* FC_EncryptFinal finishes a multiple-part encryption operation. */
 
886
 CK_RV FC_EncryptFinal(CK_SESSION_HANDLE hSession,
 
887
    CK_BYTE_PTR pLastEncryptedPart, CK_ULONG_PTR pusLastEncryptedPartLen) {
 
888
 
 
889
    SFTK_FIPSCHECK();
 
890
    return NSC_EncryptFinal(hSession,pLastEncryptedPart,
 
891
                                                pusLastEncryptedPartLen);
 
892
}
 
893
 
 
894
/*
 
895
 ************** Crypto Functions:     Decrypt ************************
 
896
 */
 
897
 
 
898
 
 
899
/* FC_DecryptInit initializes a decryption operation. */
 
900
 CK_RV FC_DecryptInit( CK_SESSION_HANDLE hSession,
 
901
                         CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) {
 
902
    SFTK_FIPSCHECK();
 
903
    rv = NSC_DecryptInit(hSession,pMechanism,hKey);
 
904
    if (sftk_audit_enabled) {
 
905
        sftk_AuditCryptInit("Decrypt",hSession,pMechanism,hKey,rv);
 
906
    }
 
907
    return rv;
 
908
}
 
909
 
 
910
/* FC_Decrypt decrypts encrypted data in a single part. */
 
911
 CK_RV FC_Decrypt(CK_SESSION_HANDLE hSession,
 
912
    CK_BYTE_PTR pEncryptedData,CK_ULONG usEncryptedDataLen,CK_BYTE_PTR pData,
 
913
                                                CK_ULONG_PTR pusDataLen) {
 
914
    SFTK_FIPSCHECK();
 
915
    return NSC_Decrypt(hSession,pEncryptedData,usEncryptedDataLen,pData,
 
916
                                                                pusDataLen);
 
917
}
 
918
 
 
919
 
 
920
/* FC_DecryptUpdate continues a multiple-part decryption operation. */
 
921
 CK_RV FC_DecryptUpdate(CK_SESSION_HANDLE hSession,
 
922
    CK_BYTE_PTR pEncryptedPart, CK_ULONG usEncryptedPartLen,
 
923
                                CK_BYTE_PTR pPart, CK_ULONG_PTR pusPartLen) {
 
924
    SFTK_FIPSCHECK();
 
925
    return NSC_DecryptUpdate(hSession,pEncryptedPart,usEncryptedPartLen,
 
926
                                                        pPart,pusPartLen);
 
927
}
 
928
 
 
929
 
 
930
/* FC_DecryptFinal finishes a multiple-part decryption operation. */
 
931
 CK_RV FC_DecryptFinal(CK_SESSION_HANDLE hSession,
 
932
    CK_BYTE_PTR pLastPart, CK_ULONG_PTR pusLastPartLen) {
 
933
    SFTK_FIPSCHECK();
 
934
    return NSC_DecryptFinal(hSession,pLastPart,pusLastPartLen);
 
935
}
 
936
 
 
937
 
 
938
/*
 
939
 ************** Crypto Functions:     Digest (HASH)  ************************
 
940
 */
 
941
 
 
942
/* FC_DigestInit initializes a message-digesting operation. */
 
943
 CK_RV FC_DigestInit(CK_SESSION_HANDLE hSession,
 
944
                                        CK_MECHANISM_PTR pMechanism) {
 
945
    SFTK_FIPSFATALCHECK();
 
946
    return NSC_DigestInit(hSession, pMechanism);
 
947
}
 
948
 
 
949
 
 
950
/* FC_Digest digests data in a single part. */
 
951
 CK_RV FC_Digest(CK_SESSION_HANDLE hSession,
 
952
    CK_BYTE_PTR pData, CK_ULONG usDataLen, CK_BYTE_PTR pDigest,
 
953
                                                CK_ULONG_PTR pusDigestLen) {
 
954
    SFTK_FIPSFATALCHECK();
 
955
    return NSC_Digest(hSession,pData,usDataLen,pDigest,pusDigestLen);
 
956
}
 
957
 
 
958
 
 
959
/* FC_DigestUpdate continues a multiple-part message-digesting operation. */
 
960
 CK_RV FC_DigestUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,
 
961
                                            CK_ULONG usPartLen) {
 
962
    SFTK_FIPSFATALCHECK();
 
963
    return NSC_DigestUpdate(hSession,pPart,usPartLen);
 
964
}
 
965
 
 
966
 
 
967
/* FC_DigestFinal finishes a multiple-part message-digesting operation. */
 
968
 CK_RV FC_DigestFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pDigest,
 
969
                                                CK_ULONG_PTR pusDigestLen) {
 
970
    SFTK_FIPSFATALCHECK();
 
971
    return NSC_DigestFinal(hSession,pDigest,pusDigestLen);
 
972
}
 
973
 
 
974
 
 
975
/*
 
976
 ************** Crypto Functions:     Sign  ************************
 
977
 */
 
978
 
 
979
/* FC_SignInit initializes a signature (private key encryption) operation,
 
980
 * where the signature is (will be) an appendix to the data, 
 
981
 * and plaintext cannot be recovered from the signature */
 
982
 CK_RV FC_SignInit(CK_SESSION_HANDLE hSession,
 
983
                 CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) {
 
984
    SFTK_FIPSCHECK();
 
985
    rv = NSC_SignInit(hSession,pMechanism,hKey);
 
986
    if (sftk_audit_enabled) {
 
987
        sftk_AuditCryptInit("Sign",hSession,pMechanism,hKey,rv);
 
988
    }
 
989
    return rv;
 
990
}
 
991
 
 
992
 
 
993
/* FC_Sign signs (encrypts with private key) data in a single part,
 
994
 * where the signature is (will be) an appendix to the data, 
 
995
 * and plaintext cannot be recovered from the signature */
 
996
 CK_RV FC_Sign(CK_SESSION_HANDLE hSession,
 
997
    CK_BYTE_PTR pData,CK_ULONG usDataLen,CK_BYTE_PTR pSignature,
 
998
                                        CK_ULONG_PTR pusSignatureLen) {
 
999
    SFTK_FIPSCHECK();
 
1000
    return NSC_Sign(hSession,pData,usDataLen,pSignature,pusSignatureLen);
 
1001
}
 
1002
 
 
1003
 
 
1004
/* FC_SignUpdate continues a multiple-part signature operation,
 
1005
 * where the signature is (will be) an appendix to the data, 
 
1006
 * and plaintext cannot be recovered from the signature */
 
1007
 CK_RV FC_SignUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,
 
1008
                                                        CK_ULONG usPartLen) {
 
1009
    SFTK_FIPSCHECK();
 
1010
    return NSC_SignUpdate(hSession,pPart,usPartLen);
 
1011
}
 
1012
 
 
1013
 
 
1014
/* FC_SignFinal finishes a multiple-part signature operation, 
 
1015
 * returning the signature. */
 
1016
 CK_RV FC_SignFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pSignature,
 
1017
                                            CK_ULONG_PTR pusSignatureLen) {
 
1018
    SFTK_FIPSCHECK();
 
1019
    return NSC_SignFinal(hSession,pSignature,pusSignatureLen);
 
1020
}
 
1021
 
 
1022
/*
 
1023
 ************** Crypto Functions:     Sign Recover  ************************
 
1024
 */
 
1025
/* FC_SignRecoverInit initializes a signature operation,
 
1026
 * where the (digest) data can be recovered from the signature. 
 
1027
 * E.g. encryption with the user's private key */
 
1028
 CK_RV FC_SignRecoverInit(CK_SESSION_HANDLE hSession,
 
1029
                         CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey) {
 
1030
    SFTK_FIPSCHECK();
 
1031
    rv = NSC_SignRecoverInit(hSession,pMechanism,hKey);
 
1032
    if (sftk_audit_enabled) {
 
1033
        sftk_AuditCryptInit("SignRecover",hSession,pMechanism,hKey,rv);
 
1034
    }
 
1035
    return rv;
 
1036
}
 
1037
 
 
1038
 
 
1039
/* FC_SignRecover signs data in a single operation
 
1040
 * where the (digest) data can be recovered from the signature. 
 
1041
 * E.g. encryption with the user's private key */
 
1042
 CK_RV FC_SignRecover(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
 
1043
  CK_ULONG usDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pusSignatureLen) {
 
1044
    SFTK_FIPSCHECK();
 
1045
    return NSC_SignRecover(hSession,pData,usDataLen,pSignature,pusSignatureLen);
 
1046
}
 
1047
 
 
1048
/*
 
1049
 ************** Crypto Functions:     verify  ************************
 
1050
 */
 
1051
 
 
1052
/* FC_VerifyInit initializes a verification operation, 
 
1053
 * where the signature is an appendix to the data, 
 
1054
 * and plaintext cannot be recovered from the signature (e.g. DSA) */
 
1055
 CK_RV FC_VerifyInit(CK_SESSION_HANDLE hSession,
 
1056
                           CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey) {
 
1057
    SFTK_FIPSCHECK();
 
1058
    rv = NSC_VerifyInit(hSession,pMechanism,hKey);
 
1059
    if (sftk_audit_enabled) {
 
1060
        sftk_AuditCryptInit("Verify",hSession,pMechanism,hKey,rv);
 
1061
    }
 
1062
    return rv;
 
1063
}
 
1064
 
 
1065
 
 
1066
/* FC_Verify verifies a signature in a single-part operation, 
 
1067
 * where the signature is an appendix to the data, 
 
1068
 * and plaintext cannot be recovered from the signature */
 
1069
 CK_RV FC_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
 
1070
    CK_ULONG usDataLen, CK_BYTE_PTR pSignature, CK_ULONG usSignatureLen) {
 
1071
    /* make sure we're legal */
 
1072
    SFTK_FIPSCHECK();
 
1073
    return NSC_Verify(hSession,pData,usDataLen,pSignature,usSignatureLen);
 
1074
}
 
1075
 
 
1076
 
 
1077
/* FC_VerifyUpdate continues a multiple-part verification operation, 
 
1078
 * where the signature is an appendix to the data, 
 
1079
 * and plaintext cannot be recovered from the signature */
 
1080
 CK_RV FC_VerifyUpdate( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
 
1081
                                                CK_ULONG usPartLen) {
 
1082
    SFTK_FIPSCHECK();
 
1083
    return NSC_VerifyUpdate(hSession,pPart,usPartLen);
 
1084
}
 
1085
 
 
1086
 
 
1087
/* FC_VerifyFinal finishes a multiple-part verification operation, 
 
1088
 * checking the signature. */
 
1089
 CK_RV FC_VerifyFinal(CK_SESSION_HANDLE hSession,
 
1090
                        CK_BYTE_PTR pSignature,CK_ULONG usSignatureLen) {
 
1091
    SFTK_FIPSCHECK();
 
1092
    return NSC_VerifyFinal(hSession,pSignature,usSignatureLen);
 
1093
}
 
1094
 
 
1095
/*
 
1096
 ************** Crypto Functions:     Verify  Recover ************************
 
1097
 */
 
1098
 
 
1099
/* FC_VerifyRecoverInit initializes a signature verification operation, 
 
1100
 * where the data is recovered from the signature. 
 
1101
 * E.g. Decryption with the user's public key */
 
1102
 CK_RV FC_VerifyRecoverInit(CK_SESSION_HANDLE hSession,
 
1103
                        CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey) {
 
1104
    SFTK_FIPSCHECK();
 
1105
    rv = NSC_VerifyRecoverInit(hSession,pMechanism,hKey);
 
1106
    if (sftk_audit_enabled) {
 
1107
        sftk_AuditCryptInit("VerifyRecover",hSession,pMechanism,hKey,rv);
 
1108
    }
 
1109
    return rv;
 
1110
}
 
1111
 
 
1112
 
 
1113
/* FC_VerifyRecover verifies a signature in a single-part operation, 
 
1114
 * where the data is recovered from the signature. 
 
1115
 * E.g. Decryption with the user's public key */
 
1116
 CK_RV FC_VerifyRecover(CK_SESSION_HANDLE hSession,
 
1117
                 CK_BYTE_PTR pSignature,CK_ULONG usSignatureLen,
 
1118
                                CK_BYTE_PTR pData,CK_ULONG_PTR pusDataLen) {
 
1119
    SFTK_FIPSCHECK();
 
1120
    return NSC_VerifyRecover(hSession,pSignature,usSignatureLen,pData,
 
1121
                                                                pusDataLen);
 
1122
}
 
1123
 
 
1124
/*
 
1125
 **************************** Key Functions:  ************************
 
1126
 */
 
1127
 
 
1128
/* FC_GenerateKey generates a secret key, creating a new key object. */
 
1129
 CK_RV FC_GenerateKey(CK_SESSION_HANDLE hSession,
 
1130
    CK_MECHANISM_PTR pMechanism,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,
 
1131
                                                CK_OBJECT_HANDLE_PTR phKey) {
 
1132
    CK_BBOOL *boolptr;
 
1133
 
 
1134
    SFTK_FIPSCHECK();
 
1135
 
 
1136
    /* all secret keys must be sensitive, if the upper level code tries to say
 
1137
     * otherwise, reject it. */
 
1138
    boolptr = (CK_BBOOL *) fc_getAttribute(pTemplate, ulCount, CKA_SENSITIVE);
 
1139
    if (boolptr != NULL) {
 
1140
        if (!(*boolptr)) {
 
1141
            return CKR_ATTRIBUTE_VALUE_INVALID;
 
1142
        }
 
1143
    }
 
1144
 
 
1145
    rv = NSC_GenerateKey(hSession,pMechanism,pTemplate,ulCount,phKey);
 
1146
    if (sftk_audit_enabled) {
 
1147
        sftk_AuditGenerateKey(hSession,pMechanism,pTemplate,ulCount,phKey,rv);
 
1148
    }
 
1149
    return rv;
 
1150
}
 
1151
 
 
1152
 
 
1153
/* FC_GenerateKeyPair generates a public-key/private-key pair, 
 
1154
 * creating new key objects. */
 
1155
 CK_RV FC_GenerateKeyPair (CK_SESSION_HANDLE hSession,
 
1156
    CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate,
 
1157
    CK_ULONG usPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
 
1158
    CK_ULONG usPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPublicKey,
 
1159
                                        CK_OBJECT_HANDLE_PTR phPrivateKey) {
 
1160
    CK_BBOOL *boolptr;
 
1161
    CK_RV crv;
 
1162
 
 
1163
    SFTK_FIPSCHECK();
 
1164
 
 
1165
    /* all private keys must be sensitive, if the upper level code tries to say
 
1166
     * otherwise, reject it. */
 
1167
    boolptr = (CK_BBOOL *) fc_getAttribute(pPrivateKeyTemplate, 
 
1168
                                usPrivateKeyAttributeCount, CKA_SENSITIVE);
 
1169
    if (boolptr != NULL) {
 
1170
        if (!(*boolptr)) {
 
1171
            return CKR_ATTRIBUTE_VALUE_INVALID;
 
1172
        }
 
1173
    }
 
1174
    crv = NSC_GenerateKeyPair (hSession,pMechanism,pPublicKeyTemplate,
 
1175
                usPublicKeyAttributeCount,pPrivateKeyTemplate,
 
1176
                usPrivateKeyAttributeCount,phPublicKey,phPrivateKey);
 
1177
    if (crv == CKR_GENERAL_ERROR) {
 
1178
        /* pairwise consistency check failed. */
 
1179
        sftk_fatalError = PR_TRUE;
 
1180
    }
 
1181
    if (sftk_audit_enabled) {
 
1182
        sftk_AuditGenerateKeyPair(hSession,pMechanism,pPublicKeyTemplate,
 
1183
                usPublicKeyAttributeCount,pPrivateKeyTemplate,
 
1184
                usPrivateKeyAttributeCount,phPublicKey,phPrivateKey,crv);
 
1185
    }
 
1186
    return crv;
 
1187
}
 
1188
 
 
1189
 
 
1190
/* FC_WrapKey wraps (i.e., encrypts) a key. */
 
1191
 CK_RV FC_WrapKey(CK_SESSION_HANDLE hSession,
 
1192
    CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey,
 
1193
    CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey,
 
1194
                                         CK_ULONG_PTR pulWrappedKeyLen) {
 
1195
    SFTK_FIPSCHECK();
 
1196
    rv = NSC_WrapKey(hSession,pMechanism,hWrappingKey,hKey,pWrappedKey,
 
1197
                                                        pulWrappedKeyLen);
 
1198
    if (sftk_audit_enabled) {
 
1199
        sftk_AuditWrapKey(hSession,pMechanism,hWrappingKey,hKey,pWrappedKey,
 
1200
                                                        pulWrappedKeyLen,rv);
 
1201
    }
 
1202
    return rv;
 
1203
}
 
1204
 
 
1205
 
 
1206
/* FC_UnwrapKey unwraps (decrypts) a wrapped key, creating a new key object. */
 
1207
 CK_RV FC_UnwrapKey(CK_SESSION_HANDLE hSession,
 
1208
    CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey,
 
1209
    CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen,
 
1210
    CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount,
 
1211
                                                 CK_OBJECT_HANDLE_PTR phKey) {
 
1212
    CK_BBOOL *boolptr;
 
1213
 
 
1214
    SFTK_FIPSCHECK();
 
1215
 
 
1216
    /* all secret keys must be sensitive, if the upper level code tries to say
 
1217
     * otherwise, reject it. */
 
1218
    boolptr = (CK_BBOOL *) fc_getAttribute(pTemplate, 
 
1219
                                        ulAttributeCount, CKA_SENSITIVE);
 
1220
    if (boolptr != NULL) {
 
1221
        if (!(*boolptr)) {
 
1222
            return CKR_ATTRIBUTE_VALUE_INVALID;
 
1223
        }
 
1224
    }
 
1225
    rv = NSC_UnwrapKey(hSession,pMechanism,hUnwrappingKey,pWrappedKey,
 
1226
                        ulWrappedKeyLen,pTemplate,ulAttributeCount,phKey);
 
1227
    if (sftk_audit_enabled) {
 
1228
        sftk_AuditUnwrapKey(hSession,pMechanism,hUnwrappingKey,pWrappedKey,
 
1229
                        ulWrappedKeyLen,pTemplate,ulAttributeCount,phKey,rv);
 
1230
    }
 
1231
    return rv;
 
1232
}
 
1233
 
 
1234
 
 
1235
/* FC_DeriveKey derives a key from a base key, creating a new key object. */
 
1236
 CK_RV FC_DeriveKey( CK_SESSION_HANDLE hSession,
 
1237
         CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey,
 
1238
         CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, 
 
1239
                                                CK_OBJECT_HANDLE_PTR phKey) {
 
1240
    CK_BBOOL *boolptr;
 
1241
 
 
1242
    SFTK_FIPSCHECK();
 
1243
 
 
1244
    /* all secret keys must be sensitive, if the upper level code tries to say
 
1245
     * otherwise, reject it. */
 
1246
    boolptr = (CK_BBOOL *) fc_getAttribute(pTemplate, 
 
1247
                                        ulAttributeCount, CKA_SENSITIVE);
 
1248
    if (boolptr != NULL) {
 
1249
        if (!(*boolptr)) {
 
1250
            return CKR_ATTRIBUTE_VALUE_INVALID;
 
1251
        }
 
1252
    }
 
1253
    rv = NSC_DeriveKey(hSession,pMechanism,hBaseKey,pTemplate,
 
1254
                        ulAttributeCount, phKey);
 
1255
    if (sftk_audit_enabled) {
 
1256
        sftk_AuditDeriveKey(hSession,pMechanism,hBaseKey,pTemplate,
 
1257
                        ulAttributeCount,phKey,rv);
 
1258
    }
 
1259
    return rv;
 
1260
}
 
1261
 
 
1262
/*
 
1263
 **************************** Radom Functions:  ************************
 
1264
 */
 
1265
 
 
1266
/* FC_SeedRandom mixes additional seed material into the token's random number 
 
1267
 * generator. */
 
1268
 CK_RV FC_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed,
 
1269
    CK_ULONG usSeedLen) {
 
1270
    CK_RV crv;
 
1271
 
 
1272
    SFTK_FIPSFATALCHECK();
 
1273
    crv = NSC_SeedRandom(hSession,pSeed,usSeedLen);
 
1274
    if (crv != CKR_OK) {
 
1275
        sftk_fatalError = PR_TRUE;
 
1276
    }
 
1277
    return crv;
 
1278
}
 
1279
 
 
1280
 
 
1281
/* FC_GenerateRandom generates random data. */
 
1282
 CK_RV FC_GenerateRandom(CK_SESSION_HANDLE hSession,
 
1283
    CK_BYTE_PTR pRandomData, CK_ULONG ulRandomLen) {
 
1284
    CK_RV crv;
 
1285
 
 
1286
    SFTK_FIPSFATALCHECK();
 
1287
    crv = NSC_GenerateRandom(hSession,pRandomData,ulRandomLen);
 
1288
    if (crv != CKR_OK) {
 
1289
        sftk_fatalError = PR_TRUE;
 
1290
        if (sftk_audit_enabled) {
 
1291
            char msg[128];
 
1292
            PR_snprintf(msg,sizeof msg,
 
1293
                        "C_GenerateRandom(hSession=0x%08lX, pRandomData=%p, "
 
1294
                        "ulRandomLen=%lu)=0x%08lX "
 
1295
                        "self-test: continuous RNG test failed",
 
1296
                        (PRUint32)hSession,pRandomData,
 
1297
                        (PRUint32)ulRandomLen,(PRUint32)crv);
 
1298
            sftk_LogAuditMessage(NSS_AUDIT_ERROR, msg);
 
1299
        }
 
1300
    }
 
1301
    return crv;
 
1302
}
 
1303
 
 
1304
 
 
1305
/* FC_GetFunctionStatus obtains an updated status of a function running 
 
1306
 * in parallel with an application. */
 
1307
 CK_RV FC_GetFunctionStatus(CK_SESSION_HANDLE hSession) {
 
1308
    SFTK_FIPSCHECK();
 
1309
    return NSC_GetFunctionStatus(hSession);
 
1310
}
 
1311
 
 
1312
 
 
1313
/* FC_CancelFunction cancels a function running in parallel */
 
1314
 CK_RV FC_CancelFunction(CK_SESSION_HANDLE hSession) {
 
1315
    SFTK_FIPSCHECK();
 
1316
    return NSC_CancelFunction(hSession);
 
1317
}
 
1318
 
 
1319
/*
 
1320
 ****************************  Version 1.1 Functions:  ************************
 
1321
 */
 
1322
 
 
1323
/* FC_GetOperationState saves the state of the cryptographic 
 
1324
 *operation in a session. */
 
1325
CK_RV FC_GetOperationState(CK_SESSION_HANDLE hSession, 
 
1326
        CK_BYTE_PTR  pOperationState, CK_ULONG_PTR pulOperationStateLen) {
 
1327
    SFTK_FIPSFATALCHECK();
 
1328
    return NSC_GetOperationState(hSession,pOperationState,pulOperationStateLen);
 
1329
}
 
1330
 
 
1331
 
 
1332
/* FC_SetOperationState restores the state of the cryptographic operation 
 
1333
 * in a session. */
 
1334
CK_RV FC_SetOperationState(CK_SESSION_HANDLE hSession, 
 
1335
        CK_BYTE_PTR  pOperationState, CK_ULONG  ulOperationStateLen,
 
1336
        CK_OBJECT_HANDLE hEncryptionKey, CK_OBJECT_HANDLE hAuthenticationKey) {
 
1337
    SFTK_FIPSFATALCHECK();
 
1338
    return NSC_SetOperationState(hSession,pOperationState,ulOperationStateLen,
 
1339
                                        hEncryptionKey,hAuthenticationKey);
 
1340
}
 
1341
 
 
1342
/* FC_FindObjectsFinal finishes a search for token and session objects. */
 
1343
CK_RV FC_FindObjectsFinal(CK_SESSION_HANDLE hSession) {
 
1344
    /* let publically readable object be found */
 
1345
    SFTK_FIPSFATALCHECK();
 
1346
    return NSC_FindObjectsFinal(hSession);
 
1347
}
 
1348
 
 
1349
 
 
1350
/* Dual-function cryptographic operations */
 
1351
 
 
1352
/* FC_DigestEncryptUpdate continues a multiple-part digesting and encryption 
 
1353
 * operation. */
 
1354
CK_RV FC_DigestEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR  pPart,
 
1355
    CK_ULONG  ulPartLen, CK_BYTE_PTR  pEncryptedPart,
 
1356
                                         CK_ULONG_PTR pulEncryptedPartLen) {
 
1357
    SFTK_FIPSCHECK();
 
1358
    return NSC_DigestEncryptUpdate(hSession,pPart,ulPartLen,pEncryptedPart,
 
1359
                                         pulEncryptedPartLen);
 
1360
}
 
1361
 
 
1362
 
 
1363
/* FC_DecryptDigestUpdate continues a multiple-part decryption and digesting 
 
1364
 * operation. */
 
1365
CK_RV FC_DecryptDigestUpdate(CK_SESSION_HANDLE hSession,
 
1366
     CK_BYTE_PTR  pEncryptedPart, CK_ULONG  ulEncryptedPartLen,
 
1367
                                CK_BYTE_PTR  pPart, CK_ULONG_PTR pulPartLen) {
 
1368
 
 
1369
    SFTK_FIPSCHECK();
 
1370
    return NSC_DecryptDigestUpdate(hSession, pEncryptedPart,ulEncryptedPartLen,
 
1371
                                pPart,pulPartLen);
 
1372
}
 
1373
 
 
1374
/* FC_SignEncryptUpdate continues a multiple-part signing and encryption 
 
1375
 * operation. */
 
1376
CK_RV FC_SignEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR  pPart,
 
1377
         CK_ULONG  ulPartLen, CK_BYTE_PTR  pEncryptedPart,
 
1378
                                         CK_ULONG_PTR pulEncryptedPartLen) {
 
1379
 
 
1380
    SFTK_FIPSCHECK();
 
1381
    return NSC_SignEncryptUpdate(hSession,pPart,ulPartLen,pEncryptedPart,
 
1382
                                         pulEncryptedPartLen);
 
1383
}
 
1384
 
 
1385
/* FC_DecryptVerifyUpdate continues a multiple-part decryption and verify 
 
1386
 * operation. */
 
1387
CK_RV FC_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession, 
 
1388
        CK_BYTE_PTR  pEncryptedData, CK_ULONG  ulEncryptedDataLen, 
 
1389
                                CK_BYTE_PTR  pData, CK_ULONG_PTR pulDataLen) {
 
1390
 
 
1391
    SFTK_FIPSCHECK();
 
1392
    return NSC_DecryptVerifyUpdate(hSession,pEncryptedData,ulEncryptedDataLen, 
 
1393
                                pData,pulDataLen);
 
1394
}
 
1395
 
 
1396
 
 
1397
/* FC_DigestKey continues a multi-part message-digesting operation,
 
1398
 * by digesting the value of a secret key as part of the data already digested.
 
1399
 */
 
1400
CK_RV FC_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey) {
 
1401
    SFTK_FIPSCHECK();
 
1402
    rv = NSC_DigestKey(hSession,hKey);
 
1403
    if (sftk_audit_enabled) {
 
1404
        sftk_AuditDigestKey(hSession,hKey,rv);
 
1405
    }
 
1406
    return rv;
 
1407
}
 
1408
 
 
1409
 
 
1410
CK_RV FC_WaitForSlotEvent(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot,
 
1411
                                                         CK_VOID_PTR pReserved)
 
1412
{
 
1413
    return NSC_WaitForSlotEvent(flags, pSlot, pReserved);
 
1414
}