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

     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/. */
     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"
    16 /* FIPS preprocessor directives for message digests             */
    17 #define FIPS_KNOWN_HASH_MESSAGE_LENGTH          64  /* 512-bits */
    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." };
    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};
    31     /* MD2 variables. */
    32     MD2Context * md2_context;
    33     unsigned int md2_bytes_hashed;
    34     PRUint8      md2_computed_digest[MD2_LENGTH];
    37     /***********************************************/
    38     /* MD2 Single-Round Known Answer Hashing Test. */
    39     /***********************************************/
    41     md2_context = MD2_NewContext();
    43     if( md2_context == NULL )
    44         return( CKR_HOST_MEMORY );
    46     MD2_Begin( md2_context );
    48     MD2_Update( md2_context, known_hash_message,
    49                 FIPS_KNOWN_HASH_MESSAGE_LENGTH );
    51     MD2_End( md2_context, md2_computed_digest, &md2_bytes_hashed, MD2_LENGTH );
    53     MD2_DestroyContext( md2_context , PR_TRUE );
    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 );
    60     return( CKR_OK );
    61 }
    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};
    73     /* MD5 variables. */
    74     PRUint8        md5_computed_digest[MD5_LENGTH];
    75     SECStatus      md5_status;
    78     /***********************************************/
    79     /* MD5 Single-Round Known Answer Hashing Test. */
    80     /***********************************************/
    82     md5_status = MD5_HashBuf( md5_computed_digest, known_hash_message,
    83                               FIPS_KNOWN_HASH_MESSAGE_LENGTH );
    85     if( ( md5_status != SECSuccess ) ||
    86         ( PORT_Memcmp( md5_computed_digest, md5_known_digest,
    87                        MD5_LENGTH ) != 0 ) )
    88         return( CKR_DEVICE_ERROR );
    90     return( CKR_OK );
    91 }
    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};
   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};
   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};
   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};
   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};
   136     /* SHA-X variables. */
   137     PRUint8        sha_computed_digest[HASH_LENGTH_MAX];
   138     SECStatus      sha_status;
   140     /*************************************************/
   141     /* SHA-1 Single-Round Known Answer Hashing Test. */
   142     /*************************************************/
   144     sha_status = SHA1_HashBuf( sha_computed_digest, known_hash_message,
   145                                 FIPS_KNOWN_HASH_MESSAGE_LENGTH );
   147     if( ( sha_status != SECSuccess ) ||
   148         ( PORT_Memcmp( sha_computed_digest, sha1_known_digest,
   149                        SHA1_LENGTH ) != 0 ) )
   150         return( CKR_DEVICE_ERROR );
   152     /***************************************************/
   153     /* SHA-224 Single-Round Known Answer Hashing Test. */
   154     /***************************************************/
   156     sha_status = SHA224_HashBuf( sha_computed_digest, known_hash_message,
   157                                 FIPS_KNOWN_HASH_MESSAGE_LENGTH );
   159     if( ( sha_status != SECSuccess ) ||
   160         ( PORT_Memcmp( sha_computed_digest, sha224_known_digest,
   161                        SHA224_LENGTH ) != 0 ) )
   162         return( CKR_DEVICE_ERROR );
   164     /***************************************************/
   165     /* SHA-256 Single-Round Known Answer Hashing Test. */
   166     /***************************************************/
   168     sha_status = SHA256_HashBuf( sha_computed_digest, known_hash_message,
   169                                 FIPS_KNOWN_HASH_MESSAGE_LENGTH );
   171     if( ( sha_status != SECSuccess ) ||
   172         ( PORT_Memcmp( sha_computed_digest, sha256_known_digest,
   173                        SHA256_LENGTH ) != 0 ) )
   174         return( CKR_DEVICE_ERROR );
   176     /***************************************************/
   177     /* SHA-384 Single-Round Known Answer Hashing Test. */
   178     /***************************************************/
   180     sha_status = SHA384_HashBuf( sha_computed_digest, known_hash_message,
   181                                 FIPS_KNOWN_HASH_MESSAGE_LENGTH );
   183     if( ( sha_status != SECSuccess ) ||
   184         ( PORT_Memcmp( sha_computed_digest, sha384_known_digest,
   185                        SHA384_LENGTH ) != 0 ) )
   186         return( CKR_DEVICE_ERROR );
   188     /***************************************************/
   189     /* SHA-512 Single-Round Known Answer Hashing Test. */
   190     /***************************************************/
   192     sha_status = SHA512_HashBuf( sha_computed_digest, known_hash_message,
   193                                 FIPS_KNOWN_HASH_MESSAGE_LENGTH );
   195     if( ( sha_status != SECSuccess ) ||
   196         ( PORT_Memcmp( sha_computed_digest, sha512_known_digest,
   197                        SHA512_LENGTH ) != 0 ) )
   198         return( CKR_DEVICE_ERROR );
   200     return( CKR_OK );
   201 }
   204 static CK_RV
   205 freebl_fipsSoftwareIntegrityTest(void)
   206 {
   207     CK_RV crv = CKR_OK;
   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 }
   216 CK_RV
   217 freebl_fipsPowerUpSelfTest( void )
   218 {
   219     CK_RV rv;
   221     /* MD2 Power-Up SelfTest(s). */
   222     rv = freebl_fips_MD2_PowerUpSelfTest();
   224     if( rv != CKR_OK )
   225         return rv;
   227     /* MD5 Power-Up SelfTest(s). */
   228     rv = freebl_fips_MD5_PowerUpSelfTest();
   230     if( rv != CKR_OK )
   231         return rv;
   233     /* SHA-X Power-Up SelfTest(s). */
   234     rv = freebl_fips_SHA_PowerUpSelfTest();
   236     if( rv != CKR_OK )
   237         return rv;
   239     /* Software/Firmware Integrity Test. */
   240     rv = freebl_fipsSoftwareIntegrityTest();
   242     if( rv != CKR_OK )
   243         return rv;
   245     /* Passed Power-Up SelfTest(s). */
   246     return( CKR_OK );
   247 }
   249 struct NSSLOWInitContextStr {
   250    int count;
   251 };
   253 struct NSSLOWHASHContextStr {
   254     const SECHashObject *hashObj;
   255     void *hashCtxt;
   257 };
   259 static int nsslow_GetFIPSEnabled(void) {
   260 #ifdef LINUX
   261     FILE *f;
   262     char d;
   263     size_t size;
   265     f = fopen("/proc/sys/crypto/fips_enabled", "r");
   266     if (!f)
   267         return 0;
   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 }
   280 static int post = 0;
   281 static int post_failed = 0;
   283 static NSSLOWInitContext dummyContext = { 0 };
   285 NSSLOWInitContext *
   286 NSSLOW_Init(void)
   287 {
   288     SECStatus rv;
   289     CK_RV crv;
   290 #ifdef FREEBL_NO_DEPEND
   291     PRBool nsprAvailable = PR_FALSE;
   294     rv = FREEBL_InitStubs();
   295     nsprAvailable = (rv ==  SECSuccess ) ? PR_TRUE : PR_FALSE;
   296 #endif
   298     if (post_failed) {
   299 	return NULL;
   300     }
   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;
   313     return &dummyContext;
   314 }
   316 void
   317 NSSLOW_Shutdown(NSSLOWInitContext *context)
   318 {
   319    PORT_Assert(context == &dummyContext);
   320    return;
   321 }
   323 void
   324 NSSLOW_Reset(NSSLOWInitContext *context)
   325 {
   326    PORT_Assert(context == &dummyContext);
   327    post_failed = 0;
   328    post = 0;
   329    return;
   330 }
   332 NSSLOWHASHContext *
   333 NSSLOWHASH_NewContext(NSSLOWInitContext *initContext, 
   334 			HASH_HashType hashType)
   335 {
   336    NSSLOWHASHContext *context;
   338    if (post_failed) {
   339 	PORT_SetError(SEC_ERROR_PKCS11_DEVICE_ERROR);
   340 	return NULL;
   341    }
   343    if (initContext != &dummyContext) {
   344 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
   345 	return (NULL);
   346    }
   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    }
   363    return context;
   364 }
   366 void
   367 NSSLOWHASH_Begin(NSSLOWHASHContext *context)
   368 {
   369    return context->hashObj->begin(context->hashCtxt);
   370 }
   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 }
   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 }
   386 void
   387 NSSLOWHASH_Destroy(NSSLOWHASHContext *context)
   388 {
   389    context->hashObj->destroy(context->hashCtxt, PR_TRUE);
   390    PORT_Free(context);
   391 }
   393 unsigned int
   394 NSSLOWHASH_Length(NSSLOWHASHContext *context)
   395 {
   396    return context->hashObj->length;
   397 }

mercurial