security/nss/lib/freebl/nsslowhash.c

branch
TOR_BUG_9701
changeset 15
b8a032363ba2
equal deleted inserted replaced
-1:000000000000 0:b989a232118c
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 "pkcs11t.h"
11 #include "blapi.h"
12 #include "hasht.h"
13 #include "plhash.h"
14 #include "nsslowhash.h"
15
16 /* FIPS preprocessor directives for message digests */
17 #define FIPS_KNOWN_HASH_MESSAGE_LENGTH 64 /* 512-bits */
18
19 /* Known Hash Message (512-bits). Used for all hashes (incl. SHA-N [N>1]). */
20 static const PRUint8 known_hash_message[] = {
21 "The test message for the MD2, MD5, and SHA-1 hashing algorithms." };
22
23 static CK_RV
24 freebl_fips_MD2_PowerUpSelfTest( void )
25 {
26 /* MD2 Known Digest Message (128-bits). */
27 static const PRUint8 md2_known_digest[] = {
28 0x41,0x5a,0x12,0xb2,0x3f,0x28,0x97,0x17,
29 0x0c,0x71,0x4e,0xcc,0x40,0xc8,0x1d,0x1b};
30
31 /* MD2 variables. */
32 MD2Context * md2_context;
33 unsigned int md2_bytes_hashed;
34 PRUint8 md2_computed_digest[MD2_LENGTH];
35
36
37 /***********************************************/
38 /* MD2 Single-Round Known Answer Hashing Test. */
39 /***********************************************/
40
41 md2_context = MD2_NewContext();
42
43 if( md2_context == NULL )
44 return( CKR_HOST_MEMORY );
45
46 MD2_Begin( md2_context );
47
48 MD2_Update( md2_context, known_hash_message,
49 FIPS_KNOWN_HASH_MESSAGE_LENGTH );
50
51 MD2_End( md2_context, md2_computed_digest, &md2_bytes_hashed, MD2_LENGTH );
52
53 MD2_DestroyContext( md2_context , PR_TRUE );
54
55 if( ( md2_bytes_hashed != MD2_LENGTH ) ||
56 ( PORT_Memcmp( md2_computed_digest, md2_known_digest,
57 MD2_LENGTH ) != 0 ) )
58 return( CKR_DEVICE_ERROR );
59
60 return( CKR_OK );
61 }
62
63
64
65 static CK_RV
66 freebl_fips_MD5_PowerUpSelfTest( void )
67 {
68 /* MD5 Known Digest Message (128-bits). */
69 static const PRUint8 md5_known_digest[] = {
70 0x25,0xc8,0xc0,0x10,0xc5,0x6e,0x68,0x28,
71 0x28,0xa4,0xa5,0xd2,0x98,0x9a,0xea,0x2d};
72
73 /* MD5 variables. */
74 PRUint8 md5_computed_digest[MD5_LENGTH];
75 SECStatus md5_status;
76
77
78 /***********************************************/
79 /* MD5 Single-Round Known Answer Hashing Test. */
80 /***********************************************/
81
82 md5_status = MD5_HashBuf( md5_computed_digest, known_hash_message,
83 FIPS_KNOWN_HASH_MESSAGE_LENGTH );
84
85 if( ( md5_status != SECSuccess ) ||
86 ( PORT_Memcmp( md5_computed_digest, md5_known_digest,
87 MD5_LENGTH ) != 0 ) )
88 return( CKR_DEVICE_ERROR );
89
90 return( CKR_OK );
91 }
92
93 static CK_RV
94 freebl_fips_SHA_PowerUpSelfTest( void )
95 {
96 /* SHA-1 Known Digest Message (160-bits). */
97 static const PRUint8 sha1_known_digest[] = {
98 0x0a,0x6d,0x07,0xba,0x1e,0xbd,0x8a,0x1b,
99 0x72,0xf6,0xc7,0x22,0xf1,0x27,0x9f,0xf0,
100 0xe0,0x68,0x47,0x7a};
101
102 /* SHA-224 Known Digest Message (224-bits). */
103 static const PRUint8 sha224_known_digest[] = {
104 0x89,0x5e,0x7f,0xfd,0x0e,0xd8,0x35,0x6f,
105 0x64,0x6d,0xf2,0xde,0x5e,0xed,0xa6,0x7f,
106 0x29,0xd1,0x12,0x73,0x42,0x84,0x95,0x4f,
107 0x8e,0x08,0xe5,0xcb};
108
109 /* SHA-256 Known Digest Message (256-bits). */
110 static const PRUint8 sha256_known_digest[] = {
111 0x38,0xa9,0xc1,0xf0,0x35,0xf6,0x5d,0x61,
112 0x11,0xd4,0x0b,0xdc,0xce,0x35,0x14,0x8d,
113 0xf2,0xdd,0xaf,0xaf,0xcf,0xb7,0x87,0xe9,
114 0x96,0xa5,0xd2,0x83,0x62,0x46,0x56,0x79};
115
116 /* SHA-384 Known Digest Message (384-bits). */
117 static const PRUint8 sha384_known_digest[] = {
118 0x11,0xfe,0x1c,0x00,0x89,0x48,0xde,0xb3,
119 0x99,0xee,0x1c,0x18,0xb4,0x10,0xfb,0xfe,
120 0xe3,0xa8,0x2c,0xf3,0x04,0xb0,0x2f,0xc8,
121 0xa3,0xc4,0x5e,0xea,0x7e,0x60,0x48,0x7b,
122 0xce,0x2c,0x62,0xf7,0xbc,0xa7,0xe8,0xa3,
123 0xcf,0x24,0xce,0x9c,0xe2,0x8b,0x09,0x72};
124
125 /* SHA-512 Known Digest Message (512-bits). */
126 static const PRUint8 sha512_known_digest[] = {
127 0xc8,0xb3,0x27,0xf9,0x0b,0x24,0xc8,0xbf,
128 0x4c,0xba,0x33,0x54,0xf2,0x31,0xbf,0xdb,
129 0xab,0xfd,0xb3,0x15,0xd7,0xfa,0x48,0x99,
130 0x07,0x60,0x0f,0x57,0x41,0x1a,0xdd,0x28,
131 0x12,0x55,0x25,0xac,0xba,0x3a,0x99,0x12,
132 0x2c,0x7a,0x8f,0x75,0x3a,0xe1,0x06,0x6f,
133 0x30,0x31,0xc9,0x33,0xc6,0x1b,0x90,0x1a,
134 0x6c,0x98,0x9a,0x87,0xd0,0xb2,0xf8,0x07};
135
136 /* SHA-X variables. */
137 PRUint8 sha_computed_digest[HASH_LENGTH_MAX];
138 SECStatus sha_status;
139
140 /*************************************************/
141 /* SHA-1 Single-Round Known Answer Hashing Test. */
142 /*************************************************/
143
144 sha_status = SHA1_HashBuf( sha_computed_digest, known_hash_message,
145 FIPS_KNOWN_HASH_MESSAGE_LENGTH );
146
147 if( ( sha_status != SECSuccess ) ||
148 ( PORT_Memcmp( sha_computed_digest, sha1_known_digest,
149 SHA1_LENGTH ) != 0 ) )
150 return( CKR_DEVICE_ERROR );
151
152 /***************************************************/
153 /* SHA-224 Single-Round Known Answer Hashing Test. */
154 /***************************************************/
155
156 sha_status = SHA224_HashBuf( sha_computed_digest, known_hash_message,
157 FIPS_KNOWN_HASH_MESSAGE_LENGTH );
158
159 if( ( sha_status != SECSuccess ) ||
160 ( PORT_Memcmp( sha_computed_digest, sha224_known_digest,
161 SHA224_LENGTH ) != 0 ) )
162 return( CKR_DEVICE_ERROR );
163
164 /***************************************************/
165 /* SHA-256 Single-Round Known Answer Hashing Test. */
166 /***************************************************/
167
168 sha_status = SHA256_HashBuf( sha_computed_digest, known_hash_message,
169 FIPS_KNOWN_HASH_MESSAGE_LENGTH );
170
171 if( ( sha_status != SECSuccess ) ||
172 ( PORT_Memcmp( sha_computed_digest, sha256_known_digest,
173 SHA256_LENGTH ) != 0 ) )
174 return( CKR_DEVICE_ERROR );
175
176 /***************************************************/
177 /* SHA-384 Single-Round Known Answer Hashing Test. */
178 /***************************************************/
179
180 sha_status = SHA384_HashBuf( sha_computed_digest, known_hash_message,
181 FIPS_KNOWN_HASH_MESSAGE_LENGTH );
182
183 if( ( sha_status != SECSuccess ) ||
184 ( PORT_Memcmp( sha_computed_digest, sha384_known_digest,
185 SHA384_LENGTH ) != 0 ) )
186 return( CKR_DEVICE_ERROR );
187
188 /***************************************************/
189 /* SHA-512 Single-Round Known Answer Hashing Test. */
190 /***************************************************/
191
192 sha_status = SHA512_HashBuf( sha_computed_digest, known_hash_message,
193 FIPS_KNOWN_HASH_MESSAGE_LENGTH );
194
195 if( ( sha_status != SECSuccess ) ||
196 ( PORT_Memcmp( sha_computed_digest, sha512_known_digest,
197 SHA512_LENGTH ) != 0 ) )
198 return( CKR_DEVICE_ERROR );
199
200 return( CKR_OK );
201 }
202
203
204 static CK_RV
205 freebl_fipsSoftwareIntegrityTest(void)
206 {
207 CK_RV crv = CKR_OK;
208
209 /* make sure that our check file signatures are OK */
210 if (!BLAPI_VerifySelf(SHLIB_PREFIX"freebl"SHLIB_VERSION"."SHLIB_SUFFIX)) {
211 crv = CKR_DEVICE_ERROR; /* better error code? checksum error? */
212 }
213 return crv;
214 }
215
216 CK_RV
217 freebl_fipsPowerUpSelfTest( void )
218 {
219 CK_RV rv;
220
221 /* MD2 Power-Up SelfTest(s). */
222 rv = freebl_fips_MD2_PowerUpSelfTest();
223
224 if( rv != CKR_OK )
225 return rv;
226
227 /* MD5 Power-Up SelfTest(s). */
228 rv = freebl_fips_MD5_PowerUpSelfTest();
229
230 if( rv != CKR_OK )
231 return rv;
232
233 /* SHA-X Power-Up SelfTest(s). */
234 rv = freebl_fips_SHA_PowerUpSelfTest();
235
236 if( rv != CKR_OK )
237 return rv;
238
239 /* Software/Firmware Integrity Test. */
240 rv = freebl_fipsSoftwareIntegrityTest();
241
242 if( rv != CKR_OK )
243 return rv;
244
245 /* Passed Power-Up SelfTest(s). */
246 return( CKR_OK );
247 }
248
249 struct NSSLOWInitContextStr {
250 int count;
251 };
252
253 struct NSSLOWHASHContextStr {
254 const SECHashObject *hashObj;
255 void *hashCtxt;
256
257 };
258
259 static int nsslow_GetFIPSEnabled(void) {
260 #ifdef LINUX
261 FILE *f;
262 char d;
263 size_t size;
264
265 f = fopen("/proc/sys/crypto/fips_enabled", "r");
266 if (!f)
267 return 0;
268
269 size = fread(&d, 1, 1, f);
270 fclose(f);
271 if (size != 1)
272 return 0;
273 if (d != '1')
274 return 0;
275 #endif
276 return 1;
277 }
278
279
280 static int post = 0;
281 static int post_failed = 0;
282
283 static NSSLOWInitContext dummyContext = { 0 };
284
285 NSSLOWInitContext *
286 NSSLOW_Init(void)
287 {
288 SECStatus rv;
289 CK_RV crv;
290 #ifdef FREEBL_NO_DEPEND
291 PRBool nsprAvailable = PR_FALSE;
292
293
294 rv = FREEBL_InitStubs();
295 nsprAvailable = (rv == SECSuccess ) ? PR_TRUE : PR_FALSE;
296 #endif
297
298 if (post_failed) {
299 return NULL;
300 }
301
302
303 if (!post && nsslow_GetFIPSEnabled()) {
304 crv = freebl_fipsPowerUpSelfTest();
305 if (crv != CKR_OK) {
306 post_failed = 1;
307 return NULL;
308 }
309 }
310 post = 1;
311
312
313 return &dummyContext;
314 }
315
316 void
317 NSSLOW_Shutdown(NSSLOWInitContext *context)
318 {
319 PORT_Assert(context == &dummyContext);
320 return;
321 }
322
323 void
324 NSSLOW_Reset(NSSLOWInitContext *context)
325 {
326 PORT_Assert(context == &dummyContext);
327 post_failed = 0;
328 post = 0;
329 return;
330 }
331
332 NSSLOWHASHContext *
333 NSSLOWHASH_NewContext(NSSLOWInitContext *initContext,
334 HASH_HashType hashType)
335 {
336 NSSLOWHASHContext *context;
337
338 if (post_failed) {
339 PORT_SetError(SEC_ERROR_PKCS11_DEVICE_ERROR);
340 return NULL;
341 }
342
343 if (initContext != &dummyContext) {
344 PORT_SetError(SEC_ERROR_INVALID_ARGS);
345 return (NULL);
346 }
347
348 context = PORT_ZNew(NSSLOWHASHContext);
349 if (!context) {
350 return NULL;
351 }
352 context->hashObj = HASH_GetRawHashObject(hashType);
353 if (!context->hashObj) {
354 PORT_Free(context);
355 return NULL;
356 }
357 context->hashCtxt = context->hashObj->create();
358 if (!context->hashCtxt) {
359 PORT_Free(context);
360 return NULL;
361 }
362
363 return context;
364 }
365
366 void
367 NSSLOWHASH_Begin(NSSLOWHASHContext *context)
368 {
369 return context->hashObj->begin(context->hashCtxt);
370 }
371
372 void
373 NSSLOWHASH_Update(NSSLOWHASHContext *context, const unsigned char *buf,
374 unsigned int len)
375 {
376 return context->hashObj->update(context->hashCtxt, buf, len);
377 }
378
379 void
380 NSSLOWHASH_End(NSSLOWHASHContext *context, unsigned char *buf,
381 unsigned int *ret, unsigned int len)
382 {
383 return context->hashObj->end(context->hashCtxt, buf, ret, len);
384 }
385
386 void
387 NSSLOWHASH_Destroy(NSSLOWHASHContext *context)
388 {
389 context->hashObj->destroy(context->hashCtxt, PR_TRUE);
390 PORT_Free(context);
391 }
392
393 unsigned int
394 NSSLOWHASH_Length(NSSLOWHASHContext *context)
395 {
396 return context->hashObj->length;
397 }

mercurial