security/nss/lib/freebl/nsslowhash.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial