int FIPS_cipher_ctx_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in) { if ((in == NULL) || (in->cipher == NULL)) { EVPerr(EVP_F_FIPS_CIPHER_CTX_COPY,EVP_R_INPUT_NOT_INITIALIZED); return 0; } /* Only FIPS ciphers allowed */ if (FIPS_module_mode() && !(in->cipher->flags & EVP_CIPH_FLAG_FIPS) && !(out->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW)) { EVPerr(EVP_F_FIPS_CIPHER_CTX_COPY, EVP_R_DISABLED_FOR_FIPS); out->cipher = &bad_cipher; return 0; } FIPS_cipher_ctx_cleanup(out); memcpy(out,in,sizeof *out); if (in->cipher_data && in->cipher->ctx_size) { out->cipher_data=OPENSSL_malloc(in->cipher->ctx_size); if (!out->cipher_data) { EVPerr(EVP_F_FIPS_CIPHER_CTX_COPY,ERR_R_MALLOC_FAILURE); return 0; } memcpy(out->cipher_data,in->cipher_data,in->cipher->ctx_size); } if (in->cipher->flags & EVP_CIPH_CUSTOM_COPY) return in->cipher->ctrl((EVP_CIPHER_CTX *)in, EVP_CTRL_COPY, 0, out); return 1; }
static int aes_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) { EVP_AES_XTS_CTX *xctx = ctx->cipher_data; if (!xctx->xts.key1 || !xctx->xts.key2) return 0; if (!out || !in || len<AES_BLOCK_SIZE) return 0; #ifdef OPENSSL_FIPS /* Requirement of SP800-38E */ if (FIPS_module_mode() && !(ctx->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW) && (len > (1UL<<20)*16)) { EVPerr(EVP_F_AES_XTS_CIPHER, EVP_R_TOO_LARGE); return 0; } #endif if (xctx->stream) (*xctx->stream)(in, out, len, xctx->xts.key1, xctx->xts.key2, ctx->iv); else if (CRYPTO_xts128_encrypt(&xctx->xts, ctx->iv, in, out, len, ctx->encrypt)) return 0; return 1; }
int FIPS_mode(void) { #ifdef OPENSSL_FIPS return FIPS_module_mode(); #else return 0; #endif }
void FIPS_rand_add(const void *buf, int num, double entropy) { if (!fips_approved_rand_meth && FIPS_module_mode()) { FIPSerr(FIPS_F_FIPS_RAND_ADD, FIPS_R_NON_FIPS_METHOD); return; } if (fips_rand_meth && fips_rand_meth->add) fips_rand_meth->add(buf, num, entropy); }
int FIPS_rand_bytes(unsigned char *buf, FIPS_RAND_SIZE_T num) { if (!fips_approved_rand_meth && FIPS_module_mode()) { FIPSerr(FIPS_F_FIPS_RAND_BYTES, FIPS_R_NON_FIPS_METHOD); return 0; } if (fips_rand_meth && fips_rand_meth->bytes) return fips_rand_meth->bytes(buf, num); return 0; }
int FIPS_rand_seed(const void *buf, FIPS_RAND_SIZE_T num) { if (!fips_approved_rand_meth && FIPS_module_mode()) { FIPSerr(FIPS_F_FIPS_RAND_SEED, FIPS_R_NON_FIPS_METHOD); return 0; } if (fips_rand_meth && fips_rand_meth->seed) fips_rand_meth->seed(buf, num); return 1; }
int FIPS_rand_pseudo_bytes(unsigned char *buf, int num) { if (!fips_approved_rand_meth && FIPS_module_mode()) { FIPSerr(FIPS_F_FIPS_RAND_PSEUDO_BYTES, FIPS_R_NON_FIPS_METHOD); return 0; } if (fips_rand_meth && fips_rand_meth->pseudorand) return fips_rand_meth->pseudorand(buf, num); return -1; }
int FIPS_rand_status(void) { if (!fips_approved_rand_meth && FIPS_module_mode()) { FIPSerr(FIPS_F_FIPS_RAND_STATUS, FIPS_R_NON_FIPS_METHOD); return 0; } if (fips_rand_meth && fips_rand_meth->status) return fips_rand_meth->status(); return 0; }
int FIPS_rand_strength(void) { if (fips_rand_bits) return fips_rand_bits; if (fips_approved_rand_meth == 1) return FIPS_drbg_get_strength(FIPS_get_default_drbg()); else if (fips_approved_rand_meth == 2) return 80; else if (fips_approved_rand_meth == 0) { if (FIPS_module_mode()) return 0; else return 256; } return 0; }
int FIPS_rand_set_method(const RAND_METHOD *meth) { if (!fips_rand_bits) { if (meth == FIPS_drbg_method()) fips_approved_rand_meth = 1; else if (meth == FIPS_x931_method()) fips_approved_rand_meth = 2; else { fips_approved_rand_meth = 0; if (FIPS_module_mode()) { FIPSerr(FIPS_F_FIPS_RAND_SET_METHOD, FIPS_R_NON_FIPS_METHOD); return 0; } } } fips_rand_meth = meth; return 1; }
int fips_check_ec_prng(EC_KEY *ec) { int bits, strength; if (!FIPS_module_mode()) return 1; if (ec->flags & (EC_FLAG_NON_FIPS_ALLOW|EC_FLAG_FIPS_CHECKED)) return 1; if (!ec->group) return 1; bits = BN_num_bits(&ec->group->order); if (bits < 160) { FIPSerr(FIPS_F_FIPS_CHECK_EC_PRNG,FIPS_R_KEY_TOO_SHORT); return 0; } /* Comparable algorithm strengths: from SP800-57 table 2 */ if (bits >= 512) strength = 256; else if (bits >= 384) strength = 192; else if (bits >= 256) strength = 128; else if (bits >= 224) strength = 112; else strength = 80; if (FIPS_rand_strength() >= strength) return 1; FIPSerr(FIPS_F_FIPS_CHECK_EC_PRNG,FIPS_R_PRNG_STRENGTH_TOO_LOW); return 0; }
int fips_check_rsa_prng(RSA *rsa, int bits) { int strength; if (!FIPS_module_mode()) return 1; if (rsa->flags & (RSA_FLAG_NON_FIPS_ALLOW|RSA_FLAG_CHECKED)) return 1; if (bits == 0) bits = BN_num_bits(rsa->n); /* Should never happen */ if (bits < 1024) { FIPSerr(FIPS_F_FIPS_CHECK_RSA_PRNG,FIPS_R_KEY_TOO_SHORT); return 0; } /* From SP800-57 */ if (bits < 2048) strength = 80; else if (bits < 3072) strength = 112; else if (bits < 7680) strength = 128; else if (bits < 15360) strength = 192; else strength = 256; if (FIPS_rand_strength() >= strength) return 1; FIPSerr(FIPS_F_FIPS_CHECK_RSA_PRNG,FIPS_R_PRNG_STRENGTH_TOO_LOW); return 0; }
int FIPS_module_mode_set(int onoff, const char *auth) { int ret = 0; fips_w_lock(); fips_started = 1; fips_set_owning_thread(); if(onoff) { fips_selftest_fail = 0; if (!fips_check_auth(auth)) { fips_auth_fail = 1; fips_selftest_fail = 1; FIPSerr(FIPS_F_FIPS_MODULE_MODE_SET,FIPS_R_AUTHENTICATION_FAILURE); return 0; } /* Don't go into FIPS mode twice, just so we can do automagic seeding */ if(FIPS_module_mode()) { FIPSerr(FIPS_F_FIPS_MODULE_MODE_SET,FIPS_R_FIPS_MODE_ALREADY_SET); fips_selftest_fail = 1; ret = 0; goto end; } #ifdef OPENSSL_IA32_SSE2 { extern unsigned int OPENSSL_ia32cap_P[2]; if ((OPENSSL_ia32cap_P[0] & (1<<25|1<<26)) != (1<<25|1<<26)) { FIPSerr(FIPS_F_FIPS_MODULE_MODE_SET,FIPS_R_UNSUPPORTED_PLATFORM); fips_selftest_fail = 1; ret = 0; goto end; } OPENSSL_ia32cap_P[0] |= (1<<28); /* set "shared cache" */ OPENSSL_ia32cap_P[1] &= ~(1<<(60-32)); /* clear AVX */ } #endif if(fips_signature_witness() != FIPS_signature) { FIPSerr(FIPS_F_FIPS_MODULE_MODE_SET,FIPS_R_CONTRADICTING_EVIDENCE); fips_selftest_fail = 1; ret = 0; goto end; } if(FIPS_selftest()) fips_set_mode(onoff); else { fips_selftest_fail = 1; ret = 0; goto end; } ret = 1; goto end; } fips_set_mode(0); fips_selftest_fail = 0; ret = 1; end: fips_clear_owning_thread(); fips_w_unlock(); return ret; }
int main(int argc,char **argv) { int bad_rsa = 0, bad_dsa = 0; int do_rng_stick = 0; int do_drbg_stick = 0; int no_exit = 0; FIPS_post_set_callback(post_cb); printf("\tFIPS-mode test application\n"); printf("\t%s\n\n", FIPS_module_version_text()); if (argv[1]) { /* Corrupted KAT tests */ if (!strcmp(argv[1], "integrity")) { fail_id = FIPS_TEST_INTEGRITY; } else if (!strcmp(argv[1], "aes")) { fail_id = FIPS_TEST_CIPHER; fail_sub = NID_aes_128_ecb; } else if (!strcmp(argv[1], "aes-ccm")) { fail_id = FIPS_TEST_CCM; } else if (!strcmp(argv[1], "aes-gcm")) { fail_id = FIPS_TEST_GCM; } else if (!strcmp(argv[1], "aes-xts")) { fail_id = FIPS_TEST_XTS; } else if (!strcmp(argv[1], "des")) { fail_id = FIPS_TEST_CIPHER; fail_sub = NID_des_ede3_ecb; } else if (!strcmp(argv[1], "dsa")) { fail_id = FIPS_TEST_SIGNATURE; fail_key = EVP_PKEY_DSA; } else if (!strcmp(argv[1], "ecdsa")) { fail_id = FIPS_TEST_SIGNATURE; fail_key = EVP_PKEY_EC; } else if (!strcmp(argv[1], "rsa")) { fail_id = FIPS_TEST_SIGNATURE; fail_key = EVP_PKEY_RSA; } else if (!strcmp(argv[1], "rsakey")) { printf("RSA key generation and signature validation with corrupted key...\n"); bad_rsa = 1; no_exit = 1; } else if (!strcmp(argv[1], "rsakeygen")) { fail_id = FIPS_TEST_PAIRWISE; fail_key = EVP_PKEY_RSA; no_exit = 1; } else if (!strcmp(argv[1], "dsakey")) { printf("DSA key generation and signature validation with corrupted key...\n"); bad_dsa = 1; no_exit = 1; } else if (!strcmp(argv[1], "dsakeygen")) { fail_id = FIPS_TEST_PAIRWISE; fail_key = EVP_PKEY_DSA; no_exit = 1; } else if (!strcmp(argv[1], "sha1")) { fail_id = FIPS_TEST_DIGEST; } else if (!strcmp(argv[1], "hmac")) { fail_id = FIPS_TEST_HMAC; } else if (!strcmp(argv[1], "cmac")) { fail_id = FIPS_TEST_CMAC; } else if (!strcmp(argv[1], "drbg")) { fail_id = FIPS_TEST_DRBG; } else if (!strcmp(argv[1], "rng")) { fail_id = FIPS_TEST_X931; } else if (!strcmp(argv[1], "post")) { fail_id = -1; } else if (!strcmp(argv[1], "rngstick")) { do_rng_stick = 1; no_exit = 1; printf("RNG test with stuck continuous test...\n"); } else if (!strcmp(argv[1], "drbgentstick")) { do_entropy_stick(); } else if (!strcmp(argv[1], "drbgstick")) { do_drbg_stick = 1; no_exit = 1; printf("DRBG test with stuck continuous test...\n"); } else { printf("Bad argument \"%s\"\n", argv[1]); exit(1); } if (!no_exit) { fips_algtest_init_nofips(); if (!FIPS_module_mode_set(1)) { printf("Power-up self test failed\n"); exit(1); } printf("Power-up self test successful\n"); exit(0); } } fips_algtest_init_nofips(); /* Non-Approved cryptographic operation */ printf("1. Non-Approved cryptographic operation test...\n"); test_msg("\ta. Included algorithm (D-H)...", dh_test()); /* Power-up self test */ ERR_clear_error(); test_msg("2. Automatic power-up self test", FIPS_module_mode_set(1)); if (!FIPS_module_mode()) exit(1); if (do_drbg_stick) FIPS_drbg_stick(); if (do_rng_stick) FIPS_x931_stick(); /* AES encryption/decryption */ test_msg("3a. AES encryption/decryption", FIPS_aes_test()); /* AES GCM encryption/decryption */ test_msg("3b. AES-GCM encryption/decryption", FIPS_aes_gcm_test()); /* RSA key generation and encryption/decryption */ test_msg("4. RSA key generation and encryption/decryption", FIPS_rsa_test(bad_rsa)); /* DES-CBC encryption/decryption */ test_msg("5. DES-ECB encryption/decryption", FIPS_des3_test()); /* DSA key generation and signature validation */ test_msg("6. DSA key generation and signature validation", FIPS_dsa_test(bad_dsa)); /* SHA-1 hash */ test_msg("7a. SHA-1 hash", FIPS_sha1_test()); /* SHA-256 hash */ test_msg("7b. SHA-256 hash", FIPS_sha256_test()); /* SHA-512 hash */ test_msg("7c. SHA-512 hash", FIPS_sha512_test()); /* HMAC-SHA-1 hash */ test_msg("7d. HMAC-SHA-1 hash", FIPS_hmac_sha1_test()); /* HMAC-SHA-224 hash */ test_msg("7e. HMAC-SHA-224 hash", FIPS_hmac_sha224_test()); /* HMAC-SHA-256 hash */ test_msg("7f. HMAC-SHA-256 hash", FIPS_hmac_sha256_test()); /* HMAC-SHA-384 hash */ test_msg("7g. HMAC-SHA-384 hash", FIPS_hmac_sha384_test()); /* HMAC-SHA-512 hash */ test_msg("7h. HMAC-SHA-512 hash", FIPS_hmac_sha512_test()); /* CMAC-AES-128 hash */ test_msg("8a. CMAC-AES-128 hash", FIPS_cmac_aes128_test()); /* CMAC-AES-192 hash */ test_msg("8b. CMAC-AES-192 hash", FIPS_cmac_aes192_test()); /* CMAC-AES-256 hash */ test_msg("8c. CMAC-AES-256 hash", FIPS_cmac_aes256_test()); # if 0 /* Not a FIPS algorithm */ /* CMAC-TDEA-2 hash */ test_msg("8d. CMAC-TDEA-2 hash", FIPS_cmac_tdea2_test()); #endif /* CMAC-TDEA-3 hash */ test_msg("8e. CMAC-TDEA-3 hash", FIPS_cmac_tdea3_test()); /* Non-Approved cryptographic operation */ printf("9. Non-Approved cryptographic operation test...\n"); printf("\ta. Included algorithm (D-H)...%s\n", dh_test() ? "successful as expected" : Fail("failed INCORRECTLY!") ); /* Zeroization */ printf("10. Zero-ization...\n\t%s\n", Zeroize() ? "successful as expected" : Fail("failed INCORRECTLY!") ); printf("\nAll tests completed with %d errors\n", Error); return Error ? 1 : 0; }
/* Actually there is no reason to insist that 'generator' be a generator. * It's just as OK (and in some sense better) to use a generator of the * order-q subgroup. */ static int dh_builtin_genparams(DH *ret, int prime_len, int generator, BN_GENCB *cb) { BIGNUM *t1,*t2; int g,ok= -1; BN_CTX *ctx=NULL; #ifdef OPENSSL_FIPS if(FIPS_selftest_failed()) { FIPSerr(FIPS_F_DH_BUILTIN_GENPARAMS,FIPS_R_FIPS_SELFTEST_FAILED); return 0; } if (FIPS_module_mode() && (prime_len < OPENSSL_DH_FIPS_MIN_MODULUS_BITS)) { DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_KEY_SIZE_TOO_SMALL); goto err; } #endif ctx=BN_CTX_new(); if (ctx == NULL) goto err; BN_CTX_start(ctx); t1 = BN_CTX_get(ctx); t2 = BN_CTX_get(ctx); if (t1 == NULL || t2 == NULL) goto err; /* Make sure 'ret' has the necessary elements */ if(!ret->p && ((ret->p = BN_new()) == NULL)) goto err; if(!ret->g && ((ret->g = BN_new()) == NULL)) goto err; if (generator <= 1) { DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_BAD_GENERATOR); goto err; } if (generator == DH_GENERATOR_2) { if (!BN_set_word(t1,24)) goto err; if (!BN_set_word(t2,11)) goto err; g=2; } #if 0 /* does not work for safe primes */ else if (generator == DH_GENERATOR_3) { if (!BN_set_word(t1,12)) goto err; if (!BN_set_word(t2,5)) goto err; g=3; } #endif else if (generator == DH_GENERATOR_5) { if (!BN_set_word(t1,10)) goto err; if (!BN_set_word(t2,3)) goto err; /* BN_set_word(t3,7); just have to miss * out on these ones :-( */ g=5; } else { /* in the general case, don't worry if 'generator' is a * generator or not: since we are using safe primes, * it will generate either an order-q or an order-2q group, * which both is OK */ if (!BN_set_word(t1,2)) goto err; if (!BN_set_word(t2,1)) goto err; g=generator; } if(!BN_generate_prime_ex(ret->p,prime_len,1,t1,t2,cb)) goto err; if(!BN_GENCB_call(cb, 3, 0)) goto err; if (!BN_set_word(ret->g,g)) goto err; ok=1; err: if (ok == -1) { DHerr(DH_F_DH_BUILTIN_GENPARAMS,ERR_R_BN_LIB); ok=0; } if (ctx != NULL) { BN_CTX_end(ctx); BN_CTX_free(ctx); } return ok; }
int FIPS_module_mode_set(int onoff, const char *auth) { int ret = 0; fips_w_lock(); fips_started = 1; fips_set_owning_thread(); if (onoff) { fips_selftest_fail = 0; /* Don't go into FIPS mode twice, just so we can do automagic seeding */ if (FIPS_module_mode()) { FIPSerr(FIPS_F_FIPS_MODULE_MODE_SET, FIPS_R_FIPS_MODE_ALREADY_SET); fips_selftest_fail = 1; ret = 0; goto end; } # ifdef OPENSSL_IA32_SSE2 { extern unsigned int OPENSSL_ia32cap_P[2]; if ((OPENSSL_ia32cap_P[0] & (1 << 25 | 1 << 26)) != (1 << 25 | 1 << 26)) { FIPSerr(FIPS_F_FIPS_MODULE_MODE_SET, FIPS_R_UNSUPPORTED_PLATFORM); fips_selftest_fail = 1; ret = 0; goto end; } } # endif if (!FIPS_selftest()) { fips_selftest_fail = 1; ret = 0; goto end; } if (!verify_checksums()) { FIPSerr(FIPS_F_FIPS_MODULE_MODE_SET, FIPS_R_FINGERPRINT_DOES_NOT_MATCH); fips_selftest_fail = 1; ret = 0; goto end; } fips_set_mode(onoff); ret = 1; goto end; } fips_set_mode(0); fips_selftest_fail = 0; ret = 1; end: fips_clear_owning_thread(); fips_w_unlock(); return ret; }
int main(int argc, char **argv) { static char buf[1024]; char **args = argv + 1; const char *sname = "fipstests.sh"; ARGS arg; int xargc; char **xargv; int lineno = 0, badarg = 0; int nerr = 0, quiet = 0, verbose = 0; int rv; FILE *in = NULL; #ifdef FIPS_ALGVS_MEMCHECK CRYPTO_malloc_debug_init(); OPENSSL_init(); CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); #endif #if defined(_TMS320C6400_PLUS) SysInit(); #endif #if (defined(__arm__) || defined(__aarch64__)) if (*args && !strcmp(*args, "-noaccel")) { extern unsigned int OPENSSL_armcap_P; OPENSSL_armcap_P=0; args++; argc--; } #endif if (*args && *args[0] != '-') { rv = run_prg(argc - 1, args); #ifdef FIPS_ALGVS_MEMCHECK CRYPTO_mem_leaks_fp(stderr); #endif return rv; } while (!badarg && *args && *args[0] == '-') { if (!strcmp(*args, "-script")) { if (args[1]) { args++; sname = *args; } else badarg = 1; } else if (!strcmp(*args, "-quiet")) quiet = 1; else if (!strcmp(*args, "-verbose")) verbose = 1; else badarg = 1; args++; } if (badarg) { fprintf(stderr, "Error processing arguments\n"); return 1; } in = fopen(sname, "r"); if (!in) { fprintf(stderr, "Error opening script file \"%s\"\n", sname); return 1; } arg.data = NULL; arg.count = 0; while (fgets(buf, sizeof(buf), in)) { lineno++; if (!chopup_args(&arg, buf, &xargc, &xargv)) fprintf(stderr, "Error processing line %d\n", lineno); else { if (!quiet) { int i; int narg = verbose ? xargc : xargc - 2; printf("Running command line:"); for (i = 0; i < narg; i++) printf(" %s", xargv[i]); printf("\n"); } rv = run_prg(xargc, xargv); if (FIPS_module_mode()) FIPS_module_mode_set(0, NULL); if (rv != 0) nerr++; if (rv == -100) fprintf(stderr, "ERROR: Command not found\n"); else if (rv != 0) fprintf(stderr, "ERROR: returned %d\n", rv); else if (verbose) printf("\tCommand run successfully\n"); } } if (!quiet) printf("Completed with %d errors\n", nerr); if (arg.data) OPENSSL_free(arg.data); fclose(in); #ifdef FIPS_ALGVS_MEMCHECK CRYPTO_mem_leaks_fp(stderr); #endif if (nerr == 0) return 0; return 1; }
int FIPS_cipherinit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, const unsigned char *key, const unsigned char *iv, int enc) { if(FIPS_selftest_failed()) { FIPSerr(FIPS_F_FIPS_CIPHERINIT,FIPS_R_FIPS_SELFTEST_FAILED); ctx->cipher = &bad_cipher; return 0; } if (enc == -1) enc = ctx->encrypt; else { if (enc) enc = 1; ctx->encrypt = enc; } if (cipher) { /* Only FIPS ciphers allowed */ if (FIPS_module_mode() && !(cipher->flags & EVP_CIPH_FLAG_FIPS) && !(ctx->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW)) { EVPerr(EVP_F_FIPS_CIPHERINIT, EVP_R_DISABLED_FOR_FIPS); ctx->cipher = &bad_cipher; return 0; } /* Ensure a context left lying around from last time is cleared * (the previous check attempted to avoid this if the same * ENGINE and EVP_CIPHER could be used). */ FIPS_cipher_ctx_cleanup(ctx); /* Restore encrypt field: it is zeroed by cleanup */ ctx->encrypt = enc; ctx->cipher=cipher; if (ctx->cipher->ctx_size) { ctx->cipher_data=OPENSSL_malloc(ctx->cipher->ctx_size); if (!ctx->cipher_data) { EVPerr(EVP_F_FIPS_CIPHERINIT, ERR_R_MALLOC_FAILURE); return 0; } } else { ctx->cipher_data = NULL; } ctx->key_len = cipher->key_len; ctx->flags = 0; if(ctx->cipher->flags & EVP_CIPH_CTRL_INIT) { if(!FIPS_cipher_ctx_ctrl(ctx, EVP_CTRL_INIT, 0, NULL)) { EVPerr(EVP_F_FIPS_CIPHERINIT, EVP_R_INITIALIZATION_ERROR); return 0; } } } else if(!ctx->cipher) { EVPerr(EVP_F_FIPS_CIPHERINIT, EVP_R_NO_CIPHER_SET); return 0; } /* we assume block size is a power of 2 in *cryptUpdate */ OPENSSL_assert(ctx->cipher->block_size == 1 || ctx->cipher->block_size == 8 || ctx->cipher->block_size == 16); if(!(M_EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_CUSTOM_IV)) { switch(M_EVP_CIPHER_CTX_mode(ctx)) { case EVP_CIPH_STREAM_CIPHER: case EVP_CIPH_ECB_MODE: break; case EVP_CIPH_CFB_MODE: case EVP_CIPH_OFB_MODE: ctx->num = 0; /* fall-through */ case EVP_CIPH_CBC_MODE: OPENSSL_assert(M_EVP_CIPHER_CTX_iv_length(ctx) <= (int)sizeof(ctx->iv)); if(iv) memcpy(ctx->oiv, iv, M_EVP_CIPHER_CTX_iv_length(ctx)); memcpy(ctx->iv, ctx->oiv, M_EVP_CIPHER_CTX_iv_length(ctx)); break; case EVP_CIPH_CTR_MODE: /* Don't reuse IV for CTR mode */ if(iv) memcpy(ctx->iv, iv, M_EVP_CIPHER_CTX_iv_length(ctx)); break; default: return 0; break; } } if(key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) { if(!ctx->cipher->init(ctx,key,iv,enc)) return 0; } ctx->buf_len=0; ctx->final_used=0; ctx->block_mask=ctx->cipher->block_size-1; return 1; }
static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) { EVP_AES_GCM_CTX *gctx = c->cipher_data; switch (type) { case EVP_CTRL_INIT: gctx->key_set = 0; gctx->iv_set = 0; gctx->ivlen = c->cipher->iv_len; gctx->iv = c->iv; gctx->taglen = -1; gctx->iv_gen = 0; gctx->tls_aad_len = -1; return 1; case EVP_CTRL_GCM_SET_IVLEN: if (arg <= 0) return 0; #ifdef OPENSSL_FIPS if (FIPS_module_mode() && !(c->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW) && arg < 12) return 0; #endif /* Allocate memory for IV if needed */ if ((arg > EVP_MAX_IV_LENGTH) && (arg > gctx->ivlen)) { if (gctx->iv != c->iv) OPENSSL_free(gctx->iv); gctx->iv = OPENSSL_malloc(arg); if (!gctx->iv) return 0; } gctx->ivlen = arg; return 1; case EVP_CTRL_GCM_SET_TAG: if (arg <= 0 || arg > 16 || c->encrypt) return 0; memcpy(c->buf, ptr, arg); gctx->taglen = arg; return 1; case EVP_CTRL_GCM_GET_TAG: if (arg <= 0 || arg > 16 || !c->encrypt || gctx->taglen < 0) return 0; memcpy(ptr, c->buf, arg); return 1; case EVP_CTRL_GCM_SET_IV_FIXED: /* Special case: -1 length restores whole IV */ if (arg == -1) { memcpy(gctx->iv, ptr, gctx->ivlen); gctx->iv_gen = 1; return 1; } /* Fixed field must be at least 4 bytes and invocation field * at least 8. */ if ((arg < 4) || (gctx->ivlen - arg) < 8) return 0; if (arg) memcpy(gctx->iv, ptr, arg); if (c->encrypt && RAND_bytes(gctx->iv + arg, gctx->ivlen - arg) <= 0) return 0; gctx->iv_gen = 1; return 1; case EVP_CTRL_GCM_IV_GEN: if (gctx->iv_gen == 0 || gctx->key_set == 0) return 0; CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen); if (arg <= 0 || arg > gctx->ivlen) arg = gctx->ivlen; memcpy(ptr, gctx->iv + gctx->ivlen - arg, arg); /* Invocation field will be at least 8 bytes in size and * so no need to check wrap around or increment more than * last 8 bytes. */ ctr64_inc(gctx->iv + gctx->ivlen - 8); gctx->iv_set = 1; return 1; case EVP_CTRL_GCM_SET_IV_INV: if (gctx->iv_gen == 0 || gctx->key_set == 0 || c->encrypt) return 0; memcpy(gctx->iv + gctx->ivlen - arg, ptr, arg); CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen); gctx->iv_set = 1; return 1; case EVP_CTRL_AEAD_TLS1_AAD: /* Save the AAD for later use */ if (arg != 13) return 0; memcpy(c->buf, ptr, arg); gctx->tls_aad_len = arg; { unsigned int len=c->buf[arg-2]<<8|c->buf[arg-1]; /* Correct length for explicit IV */ len -= EVP_GCM_TLS_EXPLICIT_IV_LEN; /* If decrypting correct for tag too */ if (!c->encrypt) len -= EVP_GCM_TLS_TAG_LEN; c->buf[arg-2] = len>>8; c->buf[arg-1] = len & 0xff; } /* Extra padding: tag appended to record */ return EVP_GCM_TLS_TAG_LEN; default: return -1; } }
static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) { BIGNUM *r0=NULL,*r1=NULL,*r2=NULL,*r3=NULL,*tmp; BIGNUM local_r0,local_d,local_p; BIGNUM *pr0,*d,*p; int bitsp,bitsq,ok= -1,n=0; BN_CTX *ctx=NULL; #ifdef OPENSSL_FIPS if(FIPS_selftest_failed()) { FIPSerr(FIPS_F_RSA_BUILTIN_KEYGEN,FIPS_R_FIPS_SELFTEST_FAILED); return 0; } if (FIPS_module_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW) && (bits < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS)) { FIPSerr(FIPS_F_RSA_BUILTIN_KEYGEN,FIPS_R_KEY_TOO_SHORT); return 0; } if (!fips_check_rsa_prng(rsa, bits)) return 0; #endif ctx=BN_CTX_new(); if (ctx == NULL) goto err; BN_CTX_start(ctx); r0 = BN_CTX_get(ctx); r1 = BN_CTX_get(ctx); r2 = BN_CTX_get(ctx); r3 = BN_CTX_get(ctx); if (r3 == NULL) goto err; bitsp=(bits+1)/2; bitsq=bits-bitsp; /* We need the RSA components non-NULL */ if(!rsa->n && ((rsa->n=BN_new()) == NULL)) goto err; if(!rsa->d && ((rsa->d=BN_new()) == NULL)) goto err; if(!rsa->e && ((rsa->e=BN_new()) == NULL)) goto err; if(!rsa->p && ((rsa->p=BN_new()) == NULL)) goto err; if(!rsa->q && ((rsa->q=BN_new()) == NULL)) goto err; if(!rsa->dmp1 && ((rsa->dmp1=BN_new()) == NULL)) goto err; if(!rsa->dmq1 && ((rsa->dmq1=BN_new()) == NULL)) goto err; if(!rsa->iqmp && ((rsa->iqmp=BN_new()) == NULL)) goto err; BN_copy(rsa->e, e_value); /* generate p and q */ for (;;) { if(!BN_generate_prime_ex(rsa->p, bitsp, 0, NULL, NULL, cb)) goto err; if (!BN_sub(r2,rsa->p,BN_value_one())) goto err; if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err; if (BN_is_one(r1)) break; if(!BN_GENCB_call(cb, 2, n++)) goto err; } if(!BN_GENCB_call(cb, 3, 0)) goto err; for (;;) { /* When generating ridiculously small keys, we can get stuck * continually regenerating the same prime values. Check for * this and bail if it happens 3 times. */ unsigned int degenerate = 0; do { if(!BN_generate_prime_ex(rsa->q, bitsq, 0, NULL, NULL, cb)) goto err; } while((BN_cmp(rsa->p, rsa->q) == 0) && (++degenerate < 3)); if(degenerate == 3) { ok = 0; /* we set our own err */ RSAerr(RSA_F_RSA_BUILTIN_KEYGEN,RSA_R_KEY_SIZE_TOO_SMALL); goto err; } if (!BN_sub(r2,rsa->q,BN_value_one())) goto err; if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err; if (BN_is_one(r1)) break; if(!BN_GENCB_call(cb, 2, n++)) goto err; } if(!BN_GENCB_call(cb, 3, 1)) goto err; if (BN_cmp(rsa->p,rsa->q) < 0) { tmp=rsa->p; rsa->p=rsa->q; rsa->q=tmp; } /* calculate n */ if (!BN_mul(rsa->n,rsa->p,rsa->q,ctx)) goto err; /* calculate d */ if (!BN_sub(r1,rsa->p,BN_value_one())) goto err; /* p-1 */ if (!BN_sub(r2,rsa->q,BN_value_one())) goto err; /* q-1 */ if (!BN_mul(r0,r1,r2,ctx)) goto err; /* (p-1)(q-1) */ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { pr0 = &local_r0; BN_with_flags(pr0, r0, BN_FLG_CONSTTIME); } else pr0 = r0; if (!BN_mod_inverse(rsa->d,rsa->e,pr0,ctx)) goto err; /* d */ /* set up d for correct BN_FLG_CONSTTIME flag */ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { d = &local_d; BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); } else d = rsa->d; /* calculate d mod (p-1) */ if (!BN_mod(rsa->dmp1,d,r1,ctx)) goto err; /* calculate d mod (q-1) */ if (!BN_mod(rsa->dmq1,d,r2,ctx)) goto err; /* calculate inverse of q mod p */ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { p = &local_p; BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME); } else p = rsa->p; if (!BN_mod_inverse(rsa->iqmp,rsa->q,p,ctx)) goto err; #ifdef OPENSSL_FIPS if(!fips_check_rsa(rsa)) goto err; #endif ok=1; err: if (ok == -1) { RSAerr(RSA_F_RSA_BUILTIN_KEYGEN,ERR_LIB_BN); ok=0; } if (ctx != NULL) { BN_CTX_end(ctx); BN_CTX_free(ctx); } return ok; }