/* * RSA: generate keys and sign, verify input plaintext. */ static int FIPS_rsa_test(int bad) { RSA *key; unsigned char input_ptext[] = "etaonrishdlc"; unsigned char buf[256]; unsigned int slen; BIGNUM *bn; EVP_MD_CTX mctx; int r = 0; ERR_clear_error(); FIPS_md_ctx_init(&mctx); key = FIPS_rsa_new(); bn = BN_new(); if (!key || !bn) return 0; BN_set_word(bn, 65537); if (!RSA_generate_key_ex(key, 2048,bn,NULL)) return 0; BN_free(bn); if (bad) BN_add_word(key->n, 1); if (!FIPS_digestinit(&mctx, EVP_sha256())) goto end; if (!FIPS_digestupdate(&mctx, input_ptext, sizeof(input_ptext) - 1)) goto end; if (!FIPS_rsa_sign_ctx(key, &mctx, RSA_PKCS1_PADDING, 0, NULL, buf, &slen)) goto end; if (!FIPS_digestinit(&mctx, EVP_sha256())) goto end; if (!FIPS_digestupdate(&mctx, input_ptext, sizeof(input_ptext) - 1)) goto end; r = FIPS_rsa_verify_ctx(key, &mctx, RSA_PKCS1_PADDING, 0, NULL, buf, slen); end: FIPS_md_ctx_cleanup(&mctx); if (key) FIPS_rsa_free(key); if (r != 1) return 0; return 1; }
/* * DSA: generate keys and sign, verify input plaintext. */ static int FIPS_dsa_test(int bad) { DSA *dsa = NULL; unsigned char dgst[] = "etaonrishdlc"; int r = 0; EVP_MD_CTX mctx; DSA_SIG *sig = NULL; ERR_clear_error(); FIPS_md_ctx_init(&mctx); dsa = FIPS_dsa_new(); if (!dsa) goto end; if (!DSA_generate_parameters_ex(dsa, 1024,NULL,0,NULL,NULL,NULL)) goto end; if (!DSA_generate_key(dsa)) goto end; if (bad) BN_add_word(dsa->pub_key, 1); if (!FIPS_digestinit(&mctx, EVP_sha256())) goto end; if (!FIPS_digestupdate(&mctx, dgst, sizeof(dgst) - 1)) goto end; sig = FIPS_dsa_sign_ctx(dsa, &mctx); if (!sig) goto end; if (!FIPS_digestinit(&mctx, EVP_sha256())) goto end; if (!FIPS_digestupdate(&mctx, dgst, sizeof(dgst) - 1)) goto end; r = FIPS_dsa_verify_ctx(dsa, &mctx, sig); end: if (sig) FIPS_dsa_sig_free(sig); FIPS_md_ctx_cleanup(&mctx); if (dsa) FIPS_dsa_free(dsa); if (r != 1) return 0; return 1; }
/* * SHA */ jlong Java_org_keysupport_provider_SHA_jniInit(JNIEnv *env, jobject obj, jint jmdid) { // LOGD("entering SHA_jniInit"); EVP_MD_CTX *ctx = 0; const EVP_MD *md; if (!(ctx = (EVP_MD_CTX *) malloc(sizeof(EVP_MD_CTX)))) { throw_exception(env, "java/lang/RuntimeException", "allocating EVP_MD_CTX"); free(ctx); return (0); } md = FIPS_get_digestbynid(jmdid); ctx = EVP_MD_CTX_create(); FIPS_digestinit(ctx, md); // LOGD("leaving SHA_jniInit"); return ((long) ctx); }
jint Java_org_keysupport_provider_ECDSASignature_jniVerifyFinal(JNIEnv *env, jobject obj, jbyteArray jmsg, jint jmdid, jbyteArray jsig) { // LOGD("entering ECDSASignature_jniVerifyFinal"); EC_Ctx *ec; EVP_MD_CTX *ctx = 0; const EVP_MD *md; jsize msgLen = 0; jsize sigLen = 0; const unsigned char *sig_ptr = NULL; if (!(ec = get_ptr(env, obj))) { LOGE("Failed to obtain key pointer"); return 0; } if (!(ctx = (EVP_MD_CTX *) malloc(sizeof(EVP_MD_CTX)))) { throw_exception(env, "java/lang/RuntimeException", "allocating EVP_MD_CTX"); destroy_ec_ctx(ec); FIPS_md_ctx_destroy(ctx); return 0; } md = FIPS_get_digestbynid(jmdid); ctx = EVP_MD_CTX_create(); msgLen = (*env)->GetArrayLength(env, jmsg); sigLen = (*env)->GetArrayLength(env, jsig); jbyte msg[msgLen]; jbyte sig[sigLen]; (*env)->GetByteArrayRegion(env, jmsg, 0, msgLen, msg); (*env)->GetByteArrayRegion(env, jsig, 0, sigLen, sig); sig_ptr = sig; ECDSA_SIG *esig = d2i_ECDSA_SIG(NULL, &sig_ptr, sigLen); FIPS_digestinit(ctx, md); int ok = FIPS_ecdsa_verify(ec->ec, msg, msgLen, md, esig); /* * This is handled a bit differently than the way OpenSSL * handles RSA Signatures, so our error handling below is a bit different. * * returns * 1: correct signature * 0: incorrect signature * -1: error */ // LOGD("FIPS_ecdsa_verify Returned: %d\n", ok); FIPS_md_ctx_destroy(ctx); FIPS_ecdsa_sig_free(esig); if (ok == 0) { throw_exception(env, "java/security/SignatureException", "Bad Signature"); return 0; } else if (ok == -1) { /* * TODO: Print any pending errors * ERR_print_errors_fp(ANDROID_LOG_ERROR); */ ERR_load_crypto_strings(); LOGE("%s", ERR_error_string(ERR_peek_error(), NULL)); throw_exception(env, "java/security/SignatureException", "jniVerifyFinal fail"); ERR_free_strings(); return 0; } // LOGD("leaving ECDSASignature_jniVerifyFinal"); return ok; }
jint Java_org_keysupport_provider_RSASignature_jniVerifyFinal(JNIEnv *env, jobject obj, jbyteArray jmsg, jint jmdid, jint jpadMode, jbyteArray jsig) { // LOGD("entering RSASignature_jniVerifyFinal"); jsize msgLen = 0; jsize sigLen = 0; RSA_Ctx *rsa; EVP_MD_CTX *ctx = 0; const EVP_MD *md; const EVP_MD *mdMgf; int saltLen = 0; LOGI("FIPS Mode of operation: %d\n", FIPS_mode()); if (!(rsa = get_ptr(env, obj))) { throw_exception(env,"java/lang/RuntimeException", "obtaining RSA_Ctx"); return 0; } if (jpadMode == RSA_PKCS1_PADDING) { // LOGD("RSA PKCS#1 v1.5 Padding"); } else if (jpadMode == RSA_PKCS1_PSS_PADDING) { // LOGD("RSA PSS Padding"); mdMgf = FIPS_get_digestbynid(jmdid); saltLen = EVP_MD_size(mdMgf); } if (!(ctx = (EVP_MD_CTX *) malloc(sizeof(EVP_MD_CTX)))) { throw_exception(env, "java/lang/RuntimeException", "allocating EVP_MD_CTX"); destroy_rsa_ctx(rsa); FIPS_md_ctx_destroy(ctx); return 0; } md = FIPS_get_digestbynid(jmdid); ctx = EVP_MD_CTX_create(); msgLen = (*env)->GetArrayLength(env, jmsg); sigLen = (*env)->GetArrayLength(env, jsig); jbyte msg[msgLen]; jbyte sig[sigLen]; (*env)->GetByteArrayRegion(env, jmsg, 0, msgLen, msg); (*env)->GetByteArrayRegion(env, jsig, 0, sigLen, sig); FIPS_digestinit(ctx, md); int ok = FIPS_rsa_verify(rsa->rsa, msg, msgLen, md, jpadMode, saltLen, mdMgf, sig, sigLen); // LOGD("FIPS_rsa_verify Returned: %d\n", ok); FIPS_md_ctx_destroy(ctx); if (ok == 0) { /* * TODO: Print any pending errors * ERR_print_errors_fp(ANDROID_LOG_ERROR); */ ERR_load_crypto_strings(); LOGE("%s\n", ERR_error_string(ERR_peek_error(), NULL)); throw_exception(env, "java/security/SignatureException", "Bad Signature"); ERR_free_strings(); return 0; } // LOGD("leaving RSASignature_jniVerifyFinal"); return ok; }
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); }
static void sigver(FILE *in, FILE *out) { DSA *dsa=NULL; char buf[1024]; char lbuf[1024]; unsigned char msg[1024]; char *keyword, *value; int n=0; int dsa2, L, N; const EVP_MD *md = NULL; DSA_SIG sg, *sig = &sg; sig->r = NULL; sig->s = NULL; while(fgets(buf,sizeof buf,in) != NULL) { if (!parse_line(&keyword, &value, lbuf, buf)) { fputs(buf,out); continue; } fputs(buf,out); if(!strcmp(keyword,"[mod")) { if (!parse_mod(value, &dsa2, &L, &N, &md)) { fprintf(stderr, "Mod Parse Error\n"); exit (1); } if (dsa) FIPS_dsa_free(dsa); dsa = FIPS_dsa_new(); } else if(!strcmp(keyword,"P")) dsa->p=hex2bn(value); else if(!strcmp(keyword,"Q")) dsa->q=hex2bn(value); else if(!strcmp(keyword,"G")) dsa->g=hex2bn(value); else if(!strcmp(keyword,"Msg")) n=hex2bin(value,msg); else if(!strcmp(keyword,"Y")) dsa->pub_key=hex2bn(value); else if(!strcmp(keyword,"R")) sig->r=hex2bn(value); else if(!strcmp(keyword,"S")) { EVP_MD_CTX mctx; int r; FIPS_md_ctx_init(&mctx); sig->s=hex2bn(value); FIPS_digestinit(&mctx, md); FIPS_digestupdate(&mctx, msg, n); no_err = 1; r = FIPS_dsa_verify_ctx(dsa, &mctx, sig); no_err = 0; FIPS_md_ctx_cleanup(&mctx); fprintf(out, "Result = %c\n\n", r == 1 ? 'P' : 'F'); } } }
static void siggen(FILE *in, FILE *out) { char buf[1024]; char lbuf[1024]; char *keyword, *value; int dsa2, L, N; const EVP_MD *md = NULL; DSA *dsa=NULL; while(fgets(buf,sizeof buf,in) != NULL) { if (!parse_line(&keyword, &value, lbuf, buf)) { fputs(buf,out); continue; } fputs(buf,out); if(!strcmp(keyword,"[mod")) { if (!parse_mod(value, &dsa2, &L, &N, &md)) { fprintf(stderr, "Mod Parse Error\n"); exit (1); } if (dsa) FIPS_dsa_free(dsa); dsa = FIPS_dsa_new(); if (!dsa2 && !dsa_builtin_paramgen(dsa, L, N, md, NULL, 0, NULL, NULL, NULL, NULL)) { fprintf(stderr, "Parameter Generation error\n"); exit(1); } if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, md, NULL, 0, NULL, NULL, NULL, NULL) <= 0) { fprintf(stderr, "Parameter Generation error\n"); exit(1); } do_bn_print_name(out, "P",dsa->p); do_bn_print_name(out, "Q",dsa->q); do_bn_print_name(out, "G",dsa->g); fputs("\n", out); } else if(!strcmp(keyword,"Msg")) { unsigned char msg[1024]; int n; EVP_MD_CTX mctx; DSA_SIG *sig; FIPS_md_ctx_init(&mctx); n=hex2bin(value,msg); if (!DSA_generate_key(dsa)) exit(1); do_bn_print_name(out, "Y",dsa->pub_key); FIPS_digestinit(&mctx, md); FIPS_digestupdate(&mctx, msg, n); sig = FIPS_dsa_sign_ctx(dsa, &mctx); do_bn_print_name(out, "R",sig->r); do_bn_print_name(out, "S",sig->s); fputs("\n", out); FIPS_dsa_sig_free(sig); FIPS_md_ctx_cleanup(&mctx); } } if (dsa) FIPS_dsa_free(dsa); }
int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) { EVP_MD_CTX_clear_flags(ctx,EVP_MD_CTX_FLAG_CLEANED); #ifndef OPENSSL_NO_ENGINE /* Whether it's nice or not, "Inits" can be used on "Final"'d contexts * so this context may already have an ENGINE! Try to avoid releasing * the previous handle, re-querying for an ENGINE, and having a * reinitialisation, when it may all be unecessary. */ if (ctx->engine && ctx->digest && (!type || (type && (type->type == ctx->digest->type)))) goto skip_to_init; if (type) { /* Ensure an ENGINE left lying around from last time is cleared * (the previous check attempted to avoid this if the same * ENGINE and EVP_MD could be used). */ if(ctx->engine) ENGINE_finish(ctx->engine); if(impl) { if (!ENGINE_init(impl)) { EVPerr(EVP_F_EVP_DIGESTINIT_EX,EVP_R_INITIALIZATION_ERROR); return 0; } } else /* Ask if an ENGINE is reserved for this job */ impl = ENGINE_get_digest_engine(type->type); if(impl) { /* There's an ENGINE for this job ... (apparently) */ const EVP_MD *d = ENGINE_get_digest(impl, type->type); if(!d) { /* Same comment from evp_enc.c */ EVPerr(EVP_F_EVP_DIGESTINIT_EX,EVP_R_INITIALIZATION_ERROR); ENGINE_finish(impl); return 0; } /* We'll use the ENGINE's private digest definition */ type = d; /* Store the ENGINE functional reference so we know * 'type' came from an ENGINE and we need to release * it when done. */ ctx->engine = impl; } else ctx->engine = NULL; } else if(!ctx->digest) { EVPerr(EVP_F_EVP_DIGESTINIT_EX,EVP_R_NO_DIGEST_SET); return 0; } #endif if (ctx->digest != type) { if (ctx->digest && ctx->digest->ctx_size) OPENSSL_free(ctx->md_data); ctx->digest=type; if (!(ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) && type->ctx_size) { ctx->update = type->update; ctx->md_data=OPENSSL_malloc(type->ctx_size); if (ctx->md_data == NULL) { EVPerr(EVP_F_EVP_DIGESTINIT_EX, ERR_R_MALLOC_FAILURE); return 0; } } } #ifndef OPENSSL_NO_ENGINE skip_to_init: #endif if (ctx->pctx) { int r; r = EVP_PKEY_CTX_ctrl(ctx->pctx, -1, EVP_PKEY_OP_TYPE_SIG, EVP_PKEY_CTRL_DIGESTINIT, 0, ctx); if (r <= 0 && (r != -2)) return 0; } if (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) return 1; #ifdef OPENSSL_FIPS if (FIPS_mode()) { if (FIPS_digestinit(ctx, type)) return 1; OPENSSL_free(ctx->md_data); ctx->md_data = NULL; return 0; } #endif return ctx->digest->init(ctx); }