/security/nss/lib/freebl/nsslowhash.c

https://bitbucket.org/MeeGoAdmin/mozilla-central/ · C · 425 lines · 262 code · 88 blank · 75 comment · 51 complexity · 2fe4ca8dc5104a5f877fc1f0ec6dbdf0 MD5 · raw file

  1. /* ***** BEGIN LICENSE BLOCK *****
  2. * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  3. *
  4. * The contents of this file are subject to the Mozilla Public License Version
  5. * 1.1 (the "License"); you may not use this file except in compliance with
  6. * the License. You may obtain a copy of the License at
  7. * http://www.mozilla.org/MPL/
  8. *
  9. * Software distributed under the License is distributed on an "AS IS" basis,
  10. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11. * for the specific language governing rights and limitations under the
  12. * License.
  13. *
  14. * The Original Code is the Netscape security libraries.
  15. *
  16. * The Initial Developer of the Original Code is
  17. * Netscape Communications Corporation.
  18. * Portions created by the Initial Developer are Copyright (C) 1994-2000
  19. * the Initial Developer. All Rights Reserved.
  20. *
  21. * Contributor(s):
  22. *
  23. * Alternatively, the contents of this file may be used under the terms of
  24. * either the GNU General Public License Version 2 or later (the "GPL"), or
  25. * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  26. * in which case the provisions of the GPL or the LGPL are applicable instead
  27. * of those above. If you wish to allow use of your version of this file only
  28. * under the terms of either the GPL or the LGPL, and not to allow others to
  29. * use your version of this file under the terms of the MPL, indicate your
  30. * decision by deleting the provisions above and replace them with the notice
  31. * and other provisions required by the GPL or the LGPL. If you do not delete
  32. * the provisions above, a recipient may use your version of this file under
  33. * the terms of any one of the MPL, the GPL or the LGPL.
  34. *
  35. * ***** END LICENSE BLOCK ***** */
  36. /* $Id: nsslowhash.c,v 1.6 2010/09/10 00:42:36 emaldona%redhat.com Exp $ */
  37. #include "stubs.h"
  38. #include "prtypes.h"
  39. #include "secerr.h"
  40. #include "pkcs11t.h"
  41. #include "blapi.h"
  42. #include "sechash.h"
  43. #include "nsslowhash.h"
  44. /* FIPS preprocessor directives for message digests */
  45. #define FIPS_KNOWN_HASH_MESSAGE_LENGTH 64 /* 512-bits */
  46. /* Known Hash Message (512-bits). Used for all hashes (incl. SHA-N [N>1]). */
  47. static const PRUint8 known_hash_message[] = {
  48. "The test message for the MD2, MD5, and SHA-1 hashing algorithms." };
  49. static CK_RV
  50. freebl_fips_MD2_PowerUpSelfTest( void )
  51. {
  52. /* MD2 Known Digest Message (128-bits). */
  53. static const PRUint8 md2_known_digest[] = {
  54. 0x41,0x5a,0x12,0xb2,0x3f,0x28,0x97,0x17,
  55. 0x0c,0x71,0x4e,0xcc,0x40,0xc8,0x1d,0x1b};
  56. /* MD2 variables. */
  57. MD2Context * md2_context;
  58. unsigned int md2_bytes_hashed;
  59. PRUint8 md2_computed_digest[MD2_LENGTH];
  60. /***********************************************/
  61. /* MD2 Single-Round Known Answer Hashing Test. */
  62. /***********************************************/
  63. md2_context = MD2_NewContext();
  64. if( md2_context == NULL )
  65. return( CKR_HOST_MEMORY );
  66. MD2_Begin( md2_context );
  67. MD2_Update( md2_context, known_hash_message,
  68. FIPS_KNOWN_HASH_MESSAGE_LENGTH );
  69. MD2_End( md2_context, md2_computed_digest, &md2_bytes_hashed, MD2_LENGTH );
  70. MD2_DestroyContext( md2_context , PR_TRUE );
  71. if( ( md2_bytes_hashed != MD2_LENGTH ) ||
  72. ( PORT_Memcmp( md2_computed_digest, md2_known_digest,
  73. MD2_LENGTH ) != 0 ) )
  74. return( CKR_DEVICE_ERROR );
  75. return( CKR_OK );
  76. }
  77. static CK_RV
  78. freebl_fips_MD5_PowerUpSelfTest( void )
  79. {
  80. /* MD5 Known Digest Message (128-bits). */
  81. static const PRUint8 md5_known_digest[] = {
  82. 0x25,0xc8,0xc0,0x10,0xc5,0x6e,0x68,0x28,
  83. 0x28,0xa4,0xa5,0xd2,0x98,0x9a,0xea,0x2d};
  84. /* MD5 variables. */
  85. PRUint8 md5_computed_digest[MD5_LENGTH];
  86. SECStatus md5_status;
  87. /***********************************************/
  88. /* MD5 Single-Round Known Answer Hashing Test. */
  89. /***********************************************/
  90. md5_status = MD5_HashBuf( md5_computed_digest, known_hash_message,
  91. FIPS_KNOWN_HASH_MESSAGE_LENGTH );
  92. if( ( md5_status != SECSuccess ) ||
  93. ( PORT_Memcmp( md5_computed_digest, md5_known_digest,
  94. MD5_LENGTH ) != 0 ) )
  95. return( CKR_DEVICE_ERROR );
  96. return( CKR_OK );
  97. }
  98. static CK_RV
  99. freebl_fips_SHA_PowerUpSelfTest( void )
  100. {
  101. /* SHA-1 Known Digest Message (160-bits). */
  102. static const PRUint8 sha1_known_digest[] = {
  103. 0x0a,0x6d,0x07,0xba,0x1e,0xbd,0x8a,0x1b,
  104. 0x72,0xf6,0xc7,0x22,0xf1,0x27,0x9f,0xf0,
  105. 0xe0,0x68,0x47,0x7a};
  106. /* SHA-224 Known Digest Message (224-bits). */
  107. static const PRUint8 sha224_known_digest[] = {
  108. 0x1c,0xc3,0x06,0x8e,0xce,0x37,0x68,0xfb,
  109. 0x1a,0x82,0x4a,0xbe,0x2b,0x00,0x51,0xf8,
  110. 0x9d,0xb6,0xe0,0x90,0x0d,0x00,0xc9,0x64,
  111. 0x9a,0xb8,0x98,0x4e};
  112. /* SHA-256 Known Digest Message (256-bits). */
  113. static const PRUint8 sha256_known_digest[] = {
  114. 0x38,0xa9,0xc1,0xf0,0x35,0xf6,0x5d,0x61,
  115. 0x11,0xd4,0x0b,0xdc,0xce,0x35,0x14,0x8d,
  116. 0xf2,0xdd,0xaf,0xaf,0xcf,0xb7,0x87,0xe9,
  117. 0x96,0xa5,0xd2,0x83,0x62,0x46,0x56,0x79};
  118. /* SHA-384 Known Digest Message (384-bits). */
  119. static const PRUint8 sha384_known_digest[] = {
  120. 0x11,0xfe,0x1c,0x00,0x89,0x48,0xde,0xb3,
  121. 0x99,0xee,0x1c,0x18,0xb4,0x10,0xfb,0xfe,
  122. 0xe3,0xa8,0x2c,0xf3,0x04,0xb0,0x2f,0xc8,
  123. 0xa3,0xc4,0x5e,0xea,0x7e,0x60,0x48,0x7b,
  124. 0xce,0x2c,0x62,0xf7,0xbc,0xa7,0xe8,0xa3,
  125. 0xcf,0x24,0xce,0x9c,0xe2,0x8b,0x09,0x72};
  126. /* SHA-512 Known Digest Message (512-bits). */
  127. static const PRUint8 sha512_known_digest[] = {
  128. 0xc8,0xb3,0x27,0xf9,0x0b,0x24,0xc8,0xbf,
  129. 0x4c,0xba,0x33,0x54,0xf2,0x31,0xbf,0xdb,
  130. 0xab,0xfd,0xb3,0x15,0xd7,0xfa,0x48,0x99,
  131. 0x07,0x60,0x0f,0x57,0x41,0x1a,0xdd,0x28,
  132. 0x12,0x55,0x25,0xac,0xba,0x3a,0x99,0x12,
  133. 0x2c,0x7a,0x8f,0x75,0x3a,0xe1,0x06,0x6f,
  134. 0x30,0x31,0xc9,0x33,0xc6,0x1b,0x90,0x1a,
  135. 0x6c,0x98,0x9a,0x87,0xd0,0xb2,0xf8,0x07};
  136. /* SHA-X variables. */
  137. PRUint8 sha_computed_digest[HASH_LENGTH_MAX];
  138. SECStatus sha_status;
  139. /*************************************************/
  140. /* SHA-1 Single-Round Known Answer Hashing Test. */
  141. /*************************************************/
  142. sha_status = SHA1_HashBuf( sha_computed_digest, known_hash_message,
  143. FIPS_KNOWN_HASH_MESSAGE_LENGTH );
  144. if( ( sha_status != SECSuccess ) ||
  145. ( PORT_Memcmp( sha_computed_digest, sha1_known_digest,
  146. SHA1_LENGTH ) != 0 ) )
  147. return( CKR_DEVICE_ERROR );
  148. /***************************************************/
  149. /* SHA-224 Single-Round Known Answer Hashing Test. */
  150. /***************************************************/
  151. sha_status = SHA224_HashBuf( sha_computed_digest, known_hash_message,
  152. FIPS_KNOWN_HASH_MESSAGE_LENGTH );
  153. if( ( sha_status != SECSuccess ) ||
  154. ( PORT_Memcmp( sha_computed_digest, sha224_known_digest,
  155. SHA224_LENGTH ) != 0 ) )
  156. return( CKR_DEVICE_ERROR );
  157. /***************************************************/
  158. /* SHA-256 Single-Round Known Answer Hashing Test. */
  159. /***************************************************/
  160. sha_status = SHA256_HashBuf( sha_computed_digest, known_hash_message,
  161. FIPS_KNOWN_HASH_MESSAGE_LENGTH );
  162. if( ( sha_status != SECSuccess ) ||
  163. ( PORT_Memcmp( sha_computed_digest, sha256_known_digest,
  164. SHA256_LENGTH ) != 0 ) )
  165. return( CKR_DEVICE_ERROR );
  166. /***************************************************/
  167. /* SHA-384 Single-Round Known Answer Hashing Test. */
  168. /***************************************************/
  169. sha_status = SHA384_HashBuf( sha_computed_digest, known_hash_message,
  170. FIPS_KNOWN_HASH_MESSAGE_LENGTH );
  171. if( ( sha_status != SECSuccess ) ||
  172. ( PORT_Memcmp( sha_computed_digest, sha384_known_digest,
  173. SHA384_LENGTH ) != 0 ) )
  174. return( CKR_DEVICE_ERROR );
  175. /***************************************************/
  176. /* SHA-512 Single-Round Known Answer Hashing Test. */
  177. /***************************************************/
  178. sha_status = SHA512_HashBuf( sha_computed_digest, known_hash_message,
  179. FIPS_KNOWN_HASH_MESSAGE_LENGTH );
  180. if( ( sha_status != SECSuccess ) ||
  181. ( PORT_Memcmp( sha_computed_digest, sha512_known_digest,
  182. SHA512_LENGTH ) != 0 ) )
  183. return( CKR_DEVICE_ERROR );
  184. return( CKR_OK );
  185. }
  186. static CK_RV
  187. freebl_fipsSoftwareIntegrityTest(void)
  188. {
  189. CK_RV crv = CKR_OK;
  190. /* make sure that our check file signatures are OK */
  191. if (!BLAPI_VerifySelf(SHLIB_PREFIX"freebl"SHLIB_VERSION"."SHLIB_SUFFIX)) {
  192. crv = CKR_DEVICE_ERROR; /* better error code? checksum error? */
  193. }
  194. return crv;
  195. }
  196. CK_RV
  197. freebl_fipsPowerUpSelfTest( void )
  198. {
  199. CK_RV rv;
  200. /* MD2 Power-Up SelfTest(s). */
  201. rv = freebl_fips_MD2_PowerUpSelfTest();
  202. if( rv != CKR_OK )
  203. return rv;
  204. /* MD5 Power-Up SelfTest(s). */
  205. rv = freebl_fips_MD5_PowerUpSelfTest();
  206. if( rv != CKR_OK )
  207. return rv;
  208. /* SHA-X Power-Up SelfTest(s). */
  209. rv = freebl_fips_SHA_PowerUpSelfTest();
  210. if( rv != CKR_OK )
  211. return rv;
  212. /* Software/Firmware Integrity Test. */
  213. rv = freebl_fipsSoftwareIntegrityTest();
  214. if( rv != CKR_OK )
  215. return rv;
  216. /* Passed Power-Up SelfTest(s). */
  217. return( CKR_OK );
  218. }
  219. struct NSSLOWInitContextStr {
  220. int count;
  221. };
  222. struct NSSLOWHASHContextStr {
  223. const SECHashObject *hashObj;
  224. void *hashCtxt;
  225. };
  226. static int nsslow_GetFIPSEnabled(void) {
  227. #ifdef LINUX
  228. FILE *f;
  229. char d;
  230. size_t size;
  231. f = fopen("/proc/sys/crypto/fips_enabled", "r");
  232. if (!f)
  233. return 0;
  234. size = fread(&d, 1, 1, f);
  235. fclose(f);
  236. if (size != 1)
  237. return 0;
  238. if (d != '1')
  239. return 0;
  240. #endif
  241. return 1;
  242. }
  243. static int post = 0;
  244. static int post_failed = 0;
  245. static NSSLOWInitContext dummyContext = { 0 };
  246. NSSLOWInitContext *
  247. NSSLOW_Init(void)
  248. {
  249. SECStatus rv;
  250. CK_RV crv;
  251. PRBool nsprAvailable = PR_FALSE;
  252. rv = FREEBL_InitStubs();
  253. nsprAvailable = (rv == SECSuccess ) ? PR_TRUE : PR_FALSE;
  254. if (post_failed) {
  255. return NULL;
  256. }
  257. if (!post && nsslow_GetFIPSEnabled()) {
  258. crv = freebl_fipsPowerUpSelfTest();
  259. if (crv != CKR_OK) {
  260. post_failed = 1;
  261. return NULL;
  262. }
  263. }
  264. post = 1;
  265. return &dummyContext;
  266. }
  267. void
  268. NSSLOW_Shutdown(NSSLOWInitContext *context)
  269. {
  270. PORT_Assert(context == &dummyContext);
  271. return;
  272. }
  273. void
  274. NSSLOW_Reset(NSSLOWInitContext *context)
  275. {
  276. PORT_Assert(context == &dummyContext);
  277. post_failed = 0;
  278. post = 0;
  279. return;
  280. }
  281. NSSLOWHASHContext *
  282. NSSLOWHASH_NewContext(NSSLOWInitContext *initContext,
  283. HASH_HashType hashType)
  284. {
  285. NSSLOWHASHContext *context;
  286. if (post_failed) {
  287. PORT_SetError(SEC_ERROR_PKCS11_DEVICE_ERROR);
  288. return NULL;
  289. }
  290. if (initContext != &dummyContext) {
  291. PORT_SetError(SEC_ERROR_INVALID_ARGS);
  292. return (NULL);
  293. }
  294. context = PORT_ZNew(NSSLOWHASHContext);
  295. if (!context) {
  296. return NULL;
  297. }
  298. context->hashObj = HASH_GetRawHashObject(hashType);
  299. if (!context->hashObj) {
  300. PORT_Free(context);
  301. return NULL;
  302. }
  303. context->hashCtxt = context->hashObj->create();
  304. if (!context->hashCtxt) {
  305. PORT_Free(context);
  306. return NULL;
  307. }
  308. return context;
  309. }
  310. void
  311. NSSLOWHASH_Begin(NSSLOWHASHContext *context)
  312. {
  313. return context->hashObj->begin(context->hashCtxt);
  314. }
  315. void
  316. NSSLOWHASH_Update(NSSLOWHASHContext *context, const unsigned char *buf,
  317. unsigned int len)
  318. {
  319. return context->hashObj->update(context->hashCtxt, buf, len);
  320. }
  321. void
  322. NSSLOWHASH_End(NSSLOWHASHContext *context, unsigned char *buf,
  323. unsigned int *ret, unsigned int len)
  324. {
  325. return context->hashObj->end(context->hashCtxt, buf, ret, len);
  326. }
  327. void
  328. NSSLOWHASH_Destroy(NSSLOWHASHContext *context)
  329. {
  330. context->hashObj->destroy(context->hashCtxt, PR_TRUE);
  331. PORT_Free(context);
  332. }
  333. unsigned int
  334. NSSLOWHASH_Length(NSSLOWHASHContext *context)
  335. {
  336. return context->hashObj->length;
  337. }