int FIPS_check_incore_fingerprint(void) { unsigned char sig[EVP_MAX_MD_SIZE]; unsigned int len; int rv = 0; #if defined(__sgi) && (defined(__mips) || defined(mips)) extern int __dso_displacement[]; #else extern int OPENSSL_NONPIC_relocated; #endif if (!fips_post_started(FIPS_TEST_INTEGRITY, 0, NULL)) return 1; if (FIPS_text_start()==NULL) { FIPSerr(FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT,FIPS_R_UNSUPPORTED_PLATFORM); goto err; } len=FIPS_incore_fingerprint(sig,sizeof(sig)); if (len!=sizeof(FIPS_signature) || memcmp(FIPS_signature,sig,sizeof(FIPS_signature))) { if (FIPS_signature>=FIPS_rodata_start && FIPS_signature<FIPS_rodata_end) FIPSerr(FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT,FIPS_R_FINGERPRINT_DOES_NOT_MATCH_SEGMENT_ALIASING); #if defined(__sgi) && (defined(__mips) || defined(mips)) else if (__dso_displacement!=NULL) #else else if (OPENSSL_NONPIC_relocated) #endif FIPSerr(FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT,FIPS_R_FINGERPRINT_DOES_NOT_MATCH_NONPIC_RELOCATED); else FIPSerr(FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT,FIPS_R_FINGERPRINT_DOES_NOT_MATCH); #ifdef OPENSSL_FIPS_DEBUGGER rv = 1; #endif goto err; } rv = 1; err: if (rv == 0) fips_post_failed(FIPS_TEST_INTEGRITY, 0, NULL); else if (!fips_post_success(FIPS_TEST_INTEGRITY, 0, NULL)) return 0; return rv; }
int fips_cipher_test(int id, EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, const unsigned char *key, const unsigned char *iv, const unsigned char *plaintext, const unsigned char *ciphertext, int len) { unsigned char pltmp[FIPS_MAX_CIPHER_TEST_SIZE]; unsigned char citmp[FIPS_MAX_CIPHER_TEST_SIZE]; int subid = M_EVP_CIPHER_nid(cipher); int rv = 0; OPENSSL_assert(len <= FIPS_MAX_CIPHER_TEST_SIZE); memset(pltmp, 0, FIPS_MAX_CIPHER_TEST_SIZE); memset(citmp, 0, FIPS_MAX_CIPHER_TEST_SIZE); if (!fips_post_started(id, subid, NULL)) return 1; if (FIPS_cipherinit(ctx, cipher, key, iv, 1) <= 0) goto error; if (!FIPS_cipher(ctx, citmp, plaintext, len)) goto error; if (memcmp(citmp, ciphertext, len)) goto error; if (!fips_post_corrupt(id, subid, NULL)) citmp[0] ^= 0x1; if (FIPS_cipherinit(ctx, cipher, key, iv, 0) <= 0) goto error; FIPS_cipher(ctx, pltmp, citmp, len); if (memcmp(pltmp, plaintext, len)) goto error; rv = 1; error: if (rv == 0) { fips_post_failed(id, subid, NULL); return 0; } return fips_post_success(id, subid, NULL); }
int FIPS_selftest_cmac() { size_t n, outlen; unsigned char out[32]; const EVP_CIPHER *cipher; CMAC_CTX *ctx = CMAC_CTX_new(); const CMAC_KAT *t; int subid = -1, rv = 1; for(n=0,t=vector; n<sizeof(vector)/sizeof(vector[0]); n++,t++) { cipher = FIPS_get_cipherbynid(t->nid); if (!cipher) { rv = -1; goto err; } subid = M_EVP_CIPHER_nid(cipher); if (!fips_post_started(FIPS_TEST_CMAC, subid, 0)) continue; if (!CMAC_Init(ctx, t->key, t->keysize/8, cipher, 0)) { rv = -1; goto err; } if (!CMAC_Update(ctx, t->msg, t->msgsize/8)) { rv = -1; goto err; } if (!fips_post_corrupt(FIPS_TEST_CMAC, subid, NULL)) { if (!CMAC_Update(ctx, t->msg, 1)) { rv = -1; goto err; } } if (!CMAC_Final(ctx, out, &outlen)) { rv = -1; goto err; } CMAC_CTX_cleanup(ctx); if(outlen < t->macsize/8 || memcmp(out,t->mac,t->macsize/8)) { fips_post_failed(FIPS_TEST_CMAC, subid, NULL); rv = 0; } else if (!fips_post_success(FIPS_TEST_CMAC, subid, NULL)) { rv = 0; goto err; } } err: CMAC_CTX_free(ctx); if (rv == -1) { fips_post_failed(FIPS_TEST_CMAC, subid, NULL); rv = 0; } if (!rv) FIPSerr(FIPS_F_FIPS_SELFTEST_CMAC,FIPS_R_SELFTEST_FAILED); return rv; }
int fips_pkey_signature_test(int id, EVP_PKEY *pkey, const unsigned char *tbs, size_t tbslen, const unsigned char *kat, size_t katlen, const EVP_MD *digest, int pad_mode, const char *fail_str) { int subid; void *ex = NULL; int ret = 0; unsigned char *sig = NULL; unsigned int siglen; static const unsigned char str1[]="12345678901234567890"; DSA_SIG *dsig = NULL; ECDSA_SIG *esig = NULL; EVP_MD_CTX mctx; FIPS_md_ctx_init(&mctx); if (tbs == NULL) tbs = str1; if (tbslen == 0) tbslen = strlen((char *)tbs); if (digest == NULL) digest = EVP_sha256(); subid = M_EVP_MD_type(digest); if (!fips_post_started(id, subid, pkey)) return 1; if (!pkey || pkey->type == EVP_PKEY_RSA) { size_t sigsize; if (!pkey) sigsize = EVP_MAX_MD_SIZE; else sigsize = RSA_size(pkey->pkey.rsa); sig = OPENSSL_malloc(sigsize); if (!sig) { FIPSerr(FIPS_F_FIPS_PKEY_SIGNATURE_TEST,ERR_R_MALLOC_FAILURE); goto error; } } if (!FIPS_digestinit(&mctx, digest)) goto error; if (!FIPS_digestupdate(&mctx, tbs, tbslen)) goto error; if (!fips_post_corrupt(id, subid, pkey)) { if (!FIPS_digestupdate(&mctx, tbs, 1)) goto error; } if (pkey == NULL) { if (!FIPS_digestfinal(&mctx, sig, &siglen)) goto error; } else if (pkey->type == EVP_PKEY_RSA) { if (!FIPS_rsa_sign_ctx(pkey->pkey.rsa, &mctx, pad_mode, 0, NULL, sig, &siglen)) goto error; } else if (pkey->type == EVP_PKEY_DSA) { dsig = FIPS_dsa_sign_ctx(pkey->pkey.dsa, &mctx); if (!dsig) goto error; } else if (pkey->type == EVP_PKEY_EC) { esig = FIPS_ecdsa_sign_ctx(pkey->pkey.ec, &mctx); if (!esig) goto error; } if (kat && ((siglen != katlen) || memcmp(kat, sig, katlen))) goto error; #if 0 { /* Debug code to print out self test KAT discrepancies */ unsigned int i; fprintf(stderr, "%s=", fail_str); for (i = 0; i < siglen; i++) fprintf(stderr, "%02X", sig[i]); fprintf(stderr, "\n"); goto error; } #endif /* If just digest test we've finished */ if (pkey == NULL) { ret = 1; /* Well actually sucess as we've set ret to 1 */ goto error; } if (!FIPS_digestinit(&mctx, digest)) goto error; if (!FIPS_digestupdate(&mctx, tbs, tbslen)) goto error; if (pkey->type == EVP_PKEY_RSA) { ret = FIPS_rsa_verify_ctx(pkey->pkey.rsa, &mctx, pad_mode, 0, NULL, sig, siglen); } else if (pkey->type == EVP_PKEY_DSA) { ret = FIPS_dsa_verify_ctx(pkey->pkey.dsa, &mctx, dsig); } else if (pkey->type == EVP_PKEY_EC) { ret = FIPS_ecdsa_verify_ctx(pkey->pkey.ec, &mctx, esig); } error: if (dsig != NULL) FIPS_dsa_sig_free(dsig); if (esig != NULL) FIPS_ecdsa_sig_free(esig); if (sig) OPENSSL_free(sig); FIPS_md_ctx_cleanup(&mctx); if (ret != 1) { FIPSerr(FIPS_F_FIPS_PKEY_SIGNATURE_TEST,FIPS_R_TEST_FAILURE); if (fail_str) FIPS_add_error_data(2, "Type=", fail_str); fips_post_failed(id, subid, ex); return 0; } return fips_post_success(id, subid, pkey); }
int FIPS_selftest_ecdh(void) { EC_KEY *ec1 = NULL, *ec2 = NULL; const EC_POINT *ecp = NULL; BIGNUM *x = NULL, *y = NULL, *d = NULL; unsigned char *ztmp = NULL; int rv = 1; size_t i; for (i = 0; i < sizeof(test_ecdh_data) / sizeof(ECDH_SELFTEST_DATA); i++) { ECDH_SELFTEST_DATA *ecd = test_ecdh_data + i; if (!fips_post_started(FIPS_TEST_ECDH, ecd->curve, 0)) continue; ztmp = OPENSSL_malloc(ecd->zlen); x = BN_bin2bn(ecd->x1, ecd->x1len, x); y = BN_bin2bn(ecd->y1, ecd->y1len, y); d = BN_bin2bn(ecd->d1, ecd->d1len, d); if (!x || !y || !d || !ztmp) { rv = -1; goto err; } ec1 = EC_KEY_new_by_curve_name(ecd->curve); if (!ec1) { rv = -1; goto err; } EC_KEY_set_flags(ec1, EC_FLAG_COFACTOR_ECDH); if (!EC_KEY_set_public_key_affine_coordinates(ec1, x, y)) { rv = -1; goto err; } if (!EC_KEY_set_private_key(ec1, d)) { rv = -1; goto err; } x = BN_bin2bn(ecd->x2, ecd->x2len, x); y = BN_bin2bn(ecd->y2, ecd->y2len, y); if (!x || !y) { rv = -1; goto err; } ec2 = EC_KEY_new_by_curve_name(ecd->curve); if (!ec2) { rv = -1; goto err; } EC_KEY_set_flags(ec1, EC_FLAG_COFACTOR_ECDH); if (!EC_KEY_set_public_key_affine_coordinates(ec2, x, y)) { rv = -1; goto err; } ecp = EC_KEY_get0_public_key(ec2); if (!ecp) { rv = -1; goto err; } if (!ECDH_compute_key(ztmp, ecd->zlen, ecp, ec1, 0)) { rv = -1; goto err; } if (!fips_post_corrupt(FIPS_TEST_ECDH, ecd->curve, NULL)) ztmp[0] ^= 0x1; if (memcmp(ztmp, ecd->z, ecd->zlen)) { fips_post_failed(FIPS_TEST_ECDH, ecd->curve, 0); rv = 0; } else if (!fips_post_success(FIPS_TEST_ECDH, ecd->curve, 0)) goto err; EC_KEY_free(ec1); ec1 = NULL; EC_KEY_free(ec2); ec2 = NULL; OPENSSL_free(ztmp); ztmp = NULL; } err: if (x) BN_clear_free(x); if (y) BN_clear_free(y); if (d) BN_clear_free(d); if (ec1) EC_KEY_free(ec1); if (ec2) EC_KEY_free(ec2); if (ztmp) OPENSSL_free(ztmp); return rv; }