1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/nss/lib/freebl/nsslowhash.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,397 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +#ifdef FREEBL_NO_DEPEND 1.9 +#include "stubs.h" 1.10 +#endif 1.11 +#include "prtypes.h" 1.12 +#include "secerr.h" 1.13 +#include "pkcs11t.h" 1.14 +#include "blapi.h" 1.15 +#include "hasht.h" 1.16 +#include "plhash.h" 1.17 +#include "nsslowhash.h" 1.18 + 1.19 +/* FIPS preprocessor directives for message digests */ 1.20 +#define FIPS_KNOWN_HASH_MESSAGE_LENGTH 64 /* 512-bits */ 1.21 + 1.22 +/* Known Hash Message (512-bits). Used for all hashes (incl. SHA-N [N>1]). */ 1.23 +static const PRUint8 known_hash_message[] = { 1.24 + "The test message for the MD2, MD5, and SHA-1 hashing algorithms." }; 1.25 + 1.26 +static CK_RV 1.27 +freebl_fips_MD2_PowerUpSelfTest( void ) 1.28 +{ 1.29 + /* MD2 Known Digest Message (128-bits). */ 1.30 + static const PRUint8 md2_known_digest[] = { 1.31 + 0x41,0x5a,0x12,0xb2,0x3f,0x28,0x97,0x17, 1.32 + 0x0c,0x71,0x4e,0xcc,0x40,0xc8,0x1d,0x1b}; 1.33 + 1.34 + /* MD2 variables. */ 1.35 + MD2Context * md2_context; 1.36 + unsigned int md2_bytes_hashed; 1.37 + PRUint8 md2_computed_digest[MD2_LENGTH]; 1.38 + 1.39 + 1.40 + /***********************************************/ 1.41 + /* MD2 Single-Round Known Answer Hashing Test. */ 1.42 + /***********************************************/ 1.43 + 1.44 + md2_context = MD2_NewContext(); 1.45 + 1.46 + if( md2_context == NULL ) 1.47 + return( CKR_HOST_MEMORY ); 1.48 + 1.49 + MD2_Begin( md2_context ); 1.50 + 1.51 + MD2_Update( md2_context, known_hash_message, 1.52 + FIPS_KNOWN_HASH_MESSAGE_LENGTH ); 1.53 + 1.54 + MD2_End( md2_context, md2_computed_digest, &md2_bytes_hashed, MD2_LENGTH ); 1.55 + 1.56 + MD2_DestroyContext( md2_context , PR_TRUE ); 1.57 + 1.58 + if( ( md2_bytes_hashed != MD2_LENGTH ) || 1.59 + ( PORT_Memcmp( md2_computed_digest, md2_known_digest, 1.60 + MD2_LENGTH ) != 0 ) ) 1.61 + return( CKR_DEVICE_ERROR ); 1.62 + 1.63 + return( CKR_OK ); 1.64 +} 1.65 + 1.66 + 1.67 + 1.68 +static CK_RV 1.69 +freebl_fips_MD5_PowerUpSelfTest( void ) 1.70 +{ 1.71 + /* MD5 Known Digest Message (128-bits). */ 1.72 + static const PRUint8 md5_known_digest[] = { 1.73 + 0x25,0xc8,0xc0,0x10,0xc5,0x6e,0x68,0x28, 1.74 + 0x28,0xa4,0xa5,0xd2,0x98,0x9a,0xea,0x2d}; 1.75 + 1.76 + /* MD5 variables. */ 1.77 + PRUint8 md5_computed_digest[MD5_LENGTH]; 1.78 + SECStatus md5_status; 1.79 + 1.80 + 1.81 + /***********************************************/ 1.82 + /* MD5 Single-Round Known Answer Hashing Test. */ 1.83 + /***********************************************/ 1.84 + 1.85 + md5_status = MD5_HashBuf( md5_computed_digest, known_hash_message, 1.86 + FIPS_KNOWN_HASH_MESSAGE_LENGTH ); 1.87 + 1.88 + if( ( md5_status != SECSuccess ) || 1.89 + ( PORT_Memcmp( md5_computed_digest, md5_known_digest, 1.90 + MD5_LENGTH ) != 0 ) ) 1.91 + return( CKR_DEVICE_ERROR ); 1.92 + 1.93 + return( CKR_OK ); 1.94 +} 1.95 + 1.96 +static CK_RV 1.97 +freebl_fips_SHA_PowerUpSelfTest( void ) 1.98 +{ 1.99 + /* SHA-1 Known Digest Message (160-bits). */ 1.100 + static const PRUint8 sha1_known_digest[] = { 1.101 + 0x0a,0x6d,0x07,0xba,0x1e,0xbd,0x8a,0x1b, 1.102 + 0x72,0xf6,0xc7,0x22,0xf1,0x27,0x9f,0xf0, 1.103 + 0xe0,0x68,0x47,0x7a}; 1.104 + 1.105 + /* SHA-224 Known Digest Message (224-bits). */ 1.106 + static const PRUint8 sha224_known_digest[] = { 1.107 + 0x89,0x5e,0x7f,0xfd,0x0e,0xd8,0x35,0x6f, 1.108 + 0x64,0x6d,0xf2,0xde,0x5e,0xed,0xa6,0x7f, 1.109 + 0x29,0xd1,0x12,0x73,0x42,0x84,0x95,0x4f, 1.110 + 0x8e,0x08,0xe5,0xcb}; 1.111 + 1.112 + /* SHA-256 Known Digest Message (256-bits). */ 1.113 + static const PRUint8 sha256_known_digest[] = { 1.114 + 0x38,0xa9,0xc1,0xf0,0x35,0xf6,0x5d,0x61, 1.115 + 0x11,0xd4,0x0b,0xdc,0xce,0x35,0x14,0x8d, 1.116 + 0xf2,0xdd,0xaf,0xaf,0xcf,0xb7,0x87,0xe9, 1.117 + 0x96,0xa5,0xd2,0x83,0x62,0x46,0x56,0x79}; 1.118 + 1.119 + /* SHA-384 Known Digest Message (384-bits). */ 1.120 + static const PRUint8 sha384_known_digest[] = { 1.121 + 0x11,0xfe,0x1c,0x00,0x89,0x48,0xde,0xb3, 1.122 + 0x99,0xee,0x1c,0x18,0xb4,0x10,0xfb,0xfe, 1.123 + 0xe3,0xa8,0x2c,0xf3,0x04,0xb0,0x2f,0xc8, 1.124 + 0xa3,0xc4,0x5e,0xea,0x7e,0x60,0x48,0x7b, 1.125 + 0xce,0x2c,0x62,0xf7,0xbc,0xa7,0xe8,0xa3, 1.126 + 0xcf,0x24,0xce,0x9c,0xe2,0x8b,0x09,0x72}; 1.127 + 1.128 + /* SHA-512 Known Digest Message (512-bits). */ 1.129 + static const PRUint8 sha512_known_digest[] = { 1.130 + 0xc8,0xb3,0x27,0xf9,0x0b,0x24,0xc8,0xbf, 1.131 + 0x4c,0xba,0x33,0x54,0xf2,0x31,0xbf,0xdb, 1.132 + 0xab,0xfd,0xb3,0x15,0xd7,0xfa,0x48,0x99, 1.133 + 0x07,0x60,0x0f,0x57,0x41,0x1a,0xdd,0x28, 1.134 + 0x12,0x55,0x25,0xac,0xba,0x3a,0x99,0x12, 1.135 + 0x2c,0x7a,0x8f,0x75,0x3a,0xe1,0x06,0x6f, 1.136 + 0x30,0x31,0xc9,0x33,0xc6,0x1b,0x90,0x1a, 1.137 + 0x6c,0x98,0x9a,0x87,0xd0,0xb2,0xf8,0x07}; 1.138 + 1.139 + /* SHA-X variables. */ 1.140 + PRUint8 sha_computed_digest[HASH_LENGTH_MAX]; 1.141 + SECStatus sha_status; 1.142 + 1.143 + /*************************************************/ 1.144 + /* SHA-1 Single-Round Known Answer Hashing Test. */ 1.145 + /*************************************************/ 1.146 + 1.147 + sha_status = SHA1_HashBuf( sha_computed_digest, known_hash_message, 1.148 + FIPS_KNOWN_HASH_MESSAGE_LENGTH ); 1.149 + 1.150 + if( ( sha_status != SECSuccess ) || 1.151 + ( PORT_Memcmp( sha_computed_digest, sha1_known_digest, 1.152 + SHA1_LENGTH ) != 0 ) ) 1.153 + return( CKR_DEVICE_ERROR ); 1.154 + 1.155 + /***************************************************/ 1.156 + /* SHA-224 Single-Round Known Answer Hashing Test. */ 1.157 + /***************************************************/ 1.158 + 1.159 + sha_status = SHA224_HashBuf( sha_computed_digest, known_hash_message, 1.160 + FIPS_KNOWN_HASH_MESSAGE_LENGTH ); 1.161 + 1.162 + if( ( sha_status != SECSuccess ) || 1.163 + ( PORT_Memcmp( sha_computed_digest, sha224_known_digest, 1.164 + SHA224_LENGTH ) != 0 ) ) 1.165 + return( CKR_DEVICE_ERROR ); 1.166 + 1.167 + /***************************************************/ 1.168 + /* SHA-256 Single-Round Known Answer Hashing Test. */ 1.169 + /***************************************************/ 1.170 + 1.171 + sha_status = SHA256_HashBuf( sha_computed_digest, known_hash_message, 1.172 + FIPS_KNOWN_HASH_MESSAGE_LENGTH ); 1.173 + 1.174 + if( ( sha_status != SECSuccess ) || 1.175 + ( PORT_Memcmp( sha_computed_digest, sha256_known_digest, 1.176 + SHA256_LENGTH ) != 0 ) ) 1.177 + return( CKR_DEVICE_ERROR ); 1.178 + 1.179 + /***************************************************/ 1.180 + /* SHA-384 Single-Round Known Answer Hashing Test. */ 1.181 + /***************************************************/ 1.182 + 1.183 + sha_status = SHA384_HashBuf( sha_computed_digest, known_hash_message, 1.184 + FIPS_KNOWN_HASH_MESSAGE_LENGTH ); 1.185 + 1.186 + if( ( sha_status != SECSuccess ) || 1.187 + ( PORT_Memcmp( sha_computed_digest, sha384_known_digest, 1.188 + SHA384_LENGTH ) != 0 ) ) 1.189 + return( CKR_DEVICE_ERROR ); 1.190 + 1.191 + /***************************************************/ 1.192 + /* SHA-512 Single-Round Known Answer Hashing Test. */ 1.193 + /***************************************************/ 1.194 + 1.195 + sha_status = SHA512_HashBuf( sha_computed_digest, known_hash_message, 1.196 + FIPS_KNOWN_HASH_MESSAGE_LENGTH ); 1.197 + 1.198 + if( ( sha_status != SECSuccess ) || 1.199 + ( PORT_Memcmp( sha_computed_digest, sha512_known_digest, 1.200 + SHA512_LENGTH ) != 0 ) ) 1.201 + return( CKR_DEVICE_ERROR ); 1.202 + 1.203 + return( CKR_OK ); 1.204 +} 1.205 + 1.206 + 1.207 +static CK_RV 1.208 +freebl_fipsSoftwareIntegrityTest(void) 1.209 +{ 1.210 + CK_RV crv = CKR_OK; 1.211 + 1.212 + /* make sure that our check file signatures are OK */ 1.213 + if (!BLAPI_VerifySelf(SHLIB_PREFIX"freebl"SHLIB_VERSION"."SHLIB_SUFFIX)) { 1.214 + crv = CKR_DEVICE_ERROR; /* better error code? checksum error? */ 1.215 + } 1.216 + return crv; 1.217 +} 1.218 + 1.219 +CK_RV 1.220 +freebl_fipsPowerUpSelfTest( void ) 1.221 +{ 1.222 + CK_RV rv; 1.223 + 1.224 + /* MD2 Power-Up SelfTest(s). */ 1.225 + rv = freebl_fips_MD2_PowerUpSelfTest(); 1.226 + 1.227 + if( rv != CKR_OK ) 1.228 + return rv; 1.229 + 1.230 + /* MD5 Power-Up SelfTest(s). */ 1.231 + rv = freebl_fips_MD5_PowerUpSelfTest(); 1.232 + 1.233 + if( rv != CKR_OK ) 1.234 + return rv; 1.235 + 1.236 + /* SHA-X Power-Up SelfTest(s). */ 1.237 + rv = freebl_fips_SHA_PowerUpSelfTest(); 1.238 + 1.239 + if( rv != CKR_OK ) 1.240 + return rv; 1.241 + 1.242 + /* Software/Firmware Integrity Test. */ 1.243 + rv = freebl_fipsSoftwareIntegrityTest(); 1.244 + 1.245 + if( rv != CKR_OK ) 1.246 + return rv; 1.247 + 1.248 + /* Passed Power-Up SelfTest(s). */ 1.249 + return( CKR_OK ); 1.250 +} 1.251 + 1.252 +struct NSSLOWInitContextStr { 1.253 + int count; 1.254 +}; 1.255 + 1.256 +struct NSSLOWHASHContextStr { 1.257 + const SECHashObject *hashObj; 1.258 + void *hashCtxt; 1.259 + 1.260 +}; 1.261 + 1.262 +static int nsslow_GetFIPSEnabled(void) { 1.263 +#ifdef LINUX 1.264 + FILE *f; 1.265 + char d; 1.266 + size_t size; 1.267 + 1.268 + f = fopen("/proc/sys/crypto/fips_enabled", "r"); 1.269 + if (!f) 1.270 + return 0; 1.271 + 1.272 + size = fread(&d, 1, 1, f); 1.273 + fclose(f); 1.274 + if (size != 1) 1.275 + return 0; 1.276 + if (d != '1') 1.277 + return 0; 1.278 +#endif 1.279 + return 1; 1.280 +} 1.281 + 1.282 + 1.283 +static int post = 0; 1.284 +static int post_failed = 0; 1.285 + 1.286 +static NSSLOWInitContext dummyContext = { 0 }; 1.287 + 1.288 +NSSLOWInitContext * 1.289 +NSSLOW_Init(void) 1.290 +{ 1.291 + SECStatus rv; 1.292 + CK_RV crv; 1.293 +#ifdef FREEBL_NO_DEPEND 1.294 + PRBool nsprAvailable = PR_FALSE; 1.295 + 1.296 + 1.297 + rv = FREEBL_InitStubs(); 1.298 + nsprAvailable = (rv == SECSuccess ) ? PR_TRUE : PR_FALSE; 1.299 +#endif 1.300 + 1.301 + if (post_failed) { 1.302 + return NULL; 1.303 + } 1.304 + 1.305 + 1.306 + if (!post && nsslow_GetFIPSEnabled()) { 1.307 + crv = freebl_fipsPowerUpSelfTest(); 1.308 + if (crv != CKR_OK) { 1.309 + post_failed = 1; 1.310 + return NULL; 1.311 + } 1.312 + } 1.313 + post = 1; 1.314 + 1.315 + 1.316 + return &dummyContext; 1.317 +} 1.318 + 1.319 +void 1.320 +NSSLOW_Shutdown(NSSLOWInitContext *context) 1.321 +{ 1.322 + PORT_Assert(context == &dummyContext); 1.323 + return; 1.324 +} 1.325 + 1.326 +void 1.327 +NSSLOW_Reset(NSSLOWInitContext *context) 1.328 +{ 1.329 + PORT_Assert(context == &dummyContext); 1.330 + post_failed = 0; 1.331 + post = 0; 1.332 + return; 1.333 +} 1.334 + 1.335 +NSSLOWHASHContext * 1.336 +NSSLOWHASH_NewContext(NSSLOWInitContext *initContext, 1.337 + HASH_HashType hashType) 1.338 +{ 1.339 + NSSLOWHASHContext *context; 1.340 + 1.341 + if (post_failed) { 1.342 + PORT_SetError(SEC_ERROR_PKCS11_DEVICE_ERROR); 1.343 + return NULL; 1.344 + } 1.345 + 1.346 + if (initContext != &dummyContext) { 1.347 + PORT_SetError(SEC_ERROR_INVALID_ARGS); 1.348 + return (NULL); 1.349 + } 1.350 + 1.351 + context = PORT_ZNew(NSSLOWHASHContext); 1.352 + if (!context) { 1.353 + return NULL; 1.354 + } 1.355 + context->hashObj = HASH_GetRawHashObject(hashType); 1.356 + if (!context->hashObj) { 1.357 + PORT_Free(context); 1.358 + return NULL; 1.359 + } 1.360 + context->hashCtxt = context->hashObj->create(); 1.361 + if (!context->hashCtxt) { 1.362 + PORT_Free(context); 1.363 + return NULL; 1.364 + } 1.365 + 1.366 + return context; 1.367 +} 1.368 + 1.369 +void 1.370 +NSSLOWHASH_Begin(NSSLOWHASHContext *context) 1.371 +{ 1.372 + return context->hashObj->begin(context->hashCtxt); 1.373 +} 1.374 + 1.375 +void 1.376 +NSSLOWHASH_Update(NSSLOWHASHContext *context, const unsigned char *buf, 1.377 + unsigned int len) 1.378 +{ 1.379 + return context->hashObj->update(context->hashCtxt, buf, len); 1.380 +} 1.381 + 1.382 +void 1.383 +NSSLOWHASH_End(NSSLOWHASHContext *context, unsigned char *buf, 1.384 + unsigned int *ret, unsigned int len) 1.385 +{ 1.386 + return context->hashObj->end(context->hashCtxt, buf, ret, len); 1.387 +} 1.388 + 1.389 +void 1.390 +NSSLOWHASH_Destroy(NSSLOWHASHContext *context) 1.391 +{ 1.392 + context->hashObj->destroy(context->hashCtxt, PR_TRUE); 1.393 + PORT_Free(context); 1.394 +} 1.395 + 1.396 +unsigned int 1.397 +NSSLOWHASH_Length(NSSLOWHASHContext *context) 1.398 +{ 1.399 + return context->hashObj->length; 1.400 +}