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 #ifdef FREEBL_NO_DEPEND
6 #include "stubs.h"
7 #endif
8 #include "prtypes.h"
9 #include "secerr.h"
10 #include "blapi.h"
11 #include "hasht.h"
12 #include "plhash.h"
13 #include "nsslowhash.h"
14 #include "blapii.h"
15
16 struct NSSLOWInitContextStr {
17 int count;
18 };
19
20 struct NSSLOWHASHContextStr {
21 const SECHashObject *hashObj;
22 void *hashCtxt;
23 };
24
25 #ifndef NSS_FIPS_DISABLED
26 static int
nsslow_GetFIPSEnabled(void)27 nsslow_GetFIPSEnabled(void)
28 {
29 #ifdef LINUX
30 FILE *f;
31 char d;
32 size_t size;
33
34 f = fopen("/proc/sys/crypto/fips_enabled", "r");
35 if (!f)
36 return 0;
37
38 size = fread(&d, 1, 1, f);
39 fclose(f);
40 if (size != 1)
41 return 0;
42 if (d != '1')
43 return 0;
44 #endif /* LINUX */
45 return 1;
46 }
47 #endif /* NSS_FIPS_DISABLED */
48
49 static NSSLOWInitContext dummyContext = { 0 };
50 static PRBool post_failed = PR_TRUE;
51
52 NSSLOWInitContext *
NSSLOW_Init(void)53 NSSLOW_Init(void)
54 {
55 #ifdef FREEBL_NO_DEPEND
56 (void)FREEBL_InitStubs();
57 #endif
58
59 #ifndef NSS_FIPS_DISABLED
60 /* make sure the FIPS product is installed if we are trying to
61 * go into FIPS mode */
62 if (nsslow_GetFIPSEnabled()) {
63 if (BL_FIPSEntryOK(PR_TRUE) != SECSuccess) {
64 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
65 post_failed = PR_TRUE;
66 return NULL;
67 }
68 }
69 #endif
70 post_failed = PR_FALSE;
71
72 return &dummyContext;
73 }
74
75 void
NSSLOW_Shutdown(NSSLOWInitContext * context)76 NSSLOW_Shutdown(NSSLOWInitContext *context)
77 {
78 PORT_Assert(context == &dummyContext);
79 return;
80 }
81
82 void
NSSLOW_Reset(NSSLOWInitContext * context)83 NSSLOW_Reset(NSSLOWInitContext *context)
84 {
85 PORT_Assert(context == &dummyContext);
86 return;
87 }
88
89 NSSLOWHASHContext *
NSSLOWHASH_NewContext(NSSLOWInitContext * initContext,HASH_HashType hashType)90 NSSLOWHASH_NewContext(NSSLOWInitContext *initContext,
91 HASH_HashType hashType)
92 {
93 NSSLOWHASHContext *context;
94
95 if (post_failed) {
96 PORT_SetError(SEC_ERROR_PKCS11_DEVICE_ERROR);
97 return NULL;
98 }
99
100 if (initContext != &dummyContext) {
101 PORT_SetError(SEC_ERROR_INVALID_ARGS);
102 return (NULL);
103 }
104
105 context = PORT_ZNew(NSSLOWHASHContext);
106 if (!context) {
107 return NULL;
108 }
109 context->hashObj = HASH_GetRawHashObject(hashType);
110 if (!context->hashObj) {
111 PORT_Free(context);
112 return NULL;
113 }
114 context->hashCtxt = context->hashObj->create();
115 if (!context->hashCtxt) {
116 PORT_Free(context);
117 return NULL;
118 }
119
120 return context;
121 }
122
123 void
NSSLOWHASH_Begin(NSSLOWHASHContext * context)124 NSSLOWHASH_Begin(NSSLOWHASHContext *context)
125 {
126 return context->hashObj->begin(context->hashCtxt);
127 }
128
129 void
NSSLOWHASH_Update(NSSLOWHASHContext * context,const unsigned char * buf,unsigned int len)130 NSSLOWHASH_Update(NSSLOWHASHContext *context, const unsigned char *buf,
131 unsigned int len)
132 {
133 return context->hashObj->update(context->hashCtxt, buf, len);
134 }
135
136 void
NSSLOWHASH_End(NSSLOWHASHContext * context,unsigned char * buf,unsigned int * ret,unsigned int len)137 NSSLOWHASH_End(NSSLOWHASHContext *context, unsigned char *buf,
138 unsigned int *ret, unsigned int len)
139 {
140 return context->hashObj->end(context->hashCtxt, buf, ret, len);
141 }
142
143 void
NSSLOWHASH_Destroy(NSSLOWHASHContext * context)144 NSSLOWHASH_Destroy(NSSLOWHASHContext *context)
145 {
146 context->hashObj->destroy(context->hashCtxt, PR_TRUE);
147 PORT_Free(context);
148 }
149
150 unsigned int
NSSLOWHASH_Length(NSSLOWHASHContext * context)151 NSSLOWHASH_Length(NSSLOWHASHContext *context)
152 {
153 return context->hashObj->length;
154 }
155