int PACE_STEP2_dec_nonce(const EAC_CTX * ctx, const PACE_SEC * pi, const BUF_MEM * enc_nonce) { BUF_MEM *key = NULL; int r = 0; check((ctx && ctx->pace_ctx && ctx->pace_ctx->ka_ctx && ctx->pace_ctx->ka_ctx->cipher), "Invalid arguments"); key = kdf_pi(pi, NULL, ctx->pace_ctx->ka_ctx, ctx->md_ctx); check(key, "Key derivation function failed"); BUF_MEM_clear_free(ctx->pace_ctx->nonce); ctx->pace_ctx->nonce = cipher_no_pad(ctx->pace_ctx->ka_ctx, ctx->cipher_ctx, key, enc_nonce, 0); check(ctx->pace_ctx->nonce, "Failed to decrypt nonce"); r = 1; err: BUF_MEM_clear_free(key); return r; }
BUF_MEM * PACE_STEP1_enc_nonce(const EAC_CTX * ctx, const PACE_SEC * pi) { BUF_MEM * enc_nonce = NULL; BUF_MEM * key = NULL; check((ctx && ctx->pace_ctx && ctx->pace_ctx->ka_ctx && ctx->pace_ctx->ka_ctx->cipher), "Invalid arguments"); key = kdf_pi(pi, NULL, ctx->pace_ctx->ka_ctx, ctx->md_ctx); check(key, "Key derivation function failed"); BUF_MEM_clear_free(ctx->pace_ctx->nonce); ctx->pace_ctx->nonce = randb(EVP_CIPHER_block_size(ctx->pace_ctx->ka_ctx->cipher)); check(ctx->pace_ctx->nonce, "Failed to create nonce"); enc_nonce = cipher_no_pad(ctx->pace_ctx->ka_ctx, ctx->cipher_ctx, key, ctx->pace_ctx->nonce, 1); err: BUF_MEM_clear_free(key); return enc_nonce; }
int ecdh_im_compute_key(PACE_CTX * ctx, const BUF_MEM * s, const BUF_MEM * in, BN_CTX *bn_ctx) { int ret = 0; BUF_MEM * x_mem = NULL; BIGNUM * a = NULL, *b = NULL, *p = NULL; BIGNUM * x = NULL, *y = NULL, *v = NULL, *u = NULL; BIGNUM * tmp = NULL, *tmp2 = NULL, *bn_inv = NULL; BIGNUM * two = NULL, *three = NULL, *four = NULL, *six = NULL; BIGNUM * twentyseven = NULL; EC_KEY *static_key = NULL, *ephemeral_key = NULL; EC_POINT *g = NULL; BN_CTX_start(bn_ctx); check((ctx && ctx->static_key && s && ctx->ka_ctx), "Invalid arguments"); static_key = EVP_PKEY_get1_EC_KEY(ctx->static_key); if (!static_key) goto err; /* Setup all the variables*/ a = BN_CTX_get(bn_ctx); b = BN_CTX_get(bn_ctx); p = BN_CTX_get(bn_ctx); x = BN_CTX_get(bn_ctx); y = BN_CTX_get(bn_ctx); v = BN_CTX_get(bn_ctx); two = BN_CTX_get(bn_ctx); three = BN_CTX_get(bn_ctx); four = BN_CTX_get(bn_ctx); six = BN_CTX_get(bn_ctx); twentyseven = BN_CTX_get(bn_ctx); tmp = BN_CTX_get(bn_ctx); tmp2 = BN_CTX_get(bn_ctx); bn_inv = BN_CTX_get(bn_ctx); if (!bn_inv) goto err; /* Encrypt the Nonce using the symmetric key in */ x_mem = cipher_no_pad(ctx->ka_ctx, NULL, in, s, 1); if (!x_mem) goto err; /* Fetch the curve parameters */ if (!EC_GROUP_get_curve_GFp(EC_KEY_get0_group(static_key), p, a, b, bn_ctx)) goto err; /* Assign constants */ if ( !BN_set_word(two,2)|| !BN_set_word(three,3)|| !BN_set_word(four,4)|| !BN_set_word(six,6)|| !BN_set_word(twentyseven,27) ) goto err; /* Check prerequisites for curve parameters */ check( /* p > 3;*/ (BN_cmp(p, three) == 1) && /* p mod 3 = 2; (p has the form p=q^n, q prime) */ BN_nnmod(tmp, p, three, bn_ctx) && (BN_cmp(tmp, two) == 0), "Unsuited curve"); /* Convert encrypted nonce to BIGNUM */ u = BN_bin2bn((unsigned char *) x_mem->data, x_mem->length, u); if (!u) goto err; if ( /* v = (3a - u^4) / 6u mod p */ !BN_mod_mul(tmp, three, a, p, bn_ctx) || !BN_mod_exp(tmp2, u, four, p, bn_ctx) || !BN_mod_sub(v, tmp, tmp2, p, bn_ctx) || !BN_mod_mul(tmp, u, six, p, bn_ctx) || /* For division within a galois field we need to compute * the multiplicative inverse of a number */ !BN_mod_inverse(bn_inv, tmp, p, bn_ctx) || !BN_mod_mul(v, v, bn_inv, p, bn_ctx) || /* x = (v^2 - b - ((u^6)/27)) */ !BN_mod_sqr(tmp, v, p, bn_ctx) || !BN_mod_sub(tmp2, tmp, b, p, bn_ctx) || !BN_mod_exp(tmp, u, six, p, bn_ctx) || !BN_mod_inverse(bn_inv, twentyseven, p, bn_ctx) || !BN_mod_mul(tmp, tmp, bn_inv, p, bn_ctx) || !BN_mod_sub(x, tmp2, tmp, p, bn_ctx) || /* x -> x^(1/3) = x^((2p^n -1)/3) */ !BN_mul(tmp, two, p, bn_ctx) || !BN_sub(tmp, tmp, BN_value_one()) || /* Division is defined, because p^n = 2 mod 3 */ !BN_div(tmp, y, tmp, three, bn_ctx) || !BN_mod_exp(tmp2, x, tmp, p, bn_ctx) || !BN_copy(x, tmp2) || /* x += (u^2)/3 */ !BN_mod_sqr(tmp, u, p, bn_ctx) || !BN_mod_inverse(bn_inv, three, p, bn_ctx) || !BN_mod_mul(tmp2, tmp, bn_inv, p, bn_ctx) || !BN_mod_add(tmp, x, tmp2, p, bn_ctx) || !BN_copy(x, tmp) || /* y = ux + v */ !BN_mod_mul(y, u, x, p, bn_ctx) || !BN_mod_add(tmp, y, v, p, bn_ctx) || !BN_copy(y, tmp) ) goto err; /* Initialize ephemeral parameters with parameters from the static key */ ephemeral_key = EC_KEY_dup(static_key); if (!ephemeral_key) goto err; EVP_PKEY_set1_EC_KEY(ctx->ka_ctx->key, ephemeral_key); /* configure the new EC_KEY */ g = EC_POINT_new(EC_KEY_get0_group(ephemeral_key)); if (!g) goto err; if (!EC_POINT_set_affine_coordinates_GFp(EC_KEY_get0_group(ephemeral_key), g, x, y, bn_ctx)) goto err; ret = 1; err: if (x_mem) BUF_MEM_free(x_mem); if (u) BN_free(u); BN_CTX_end(bn_ctx); if (g) EC_POINT_clear_free(g); /* Decrement reference count, keys are still available via PACE_CTX */ if (static_key) EC_KEY_free(static_key); if (ephemeral_key) EC_KEY_free(ephemeral_key); return ret; }
int update_iv(KA_CTX *ctx, EVP_CIPHER_CTX *cipher_ctx, const BIGNUM *ssc) { BUF_MEM *sscbuf = NULL, *ivbuf = NULL; const EVP_CIPHER *ivcipher = NULL, *oldcipher; unsigned char *ssc_buf = NULL; unsigned char *p; int r = 0; check(ctx, "Invalid arguments"); switch (EVP_CIPHER_nid(ctx->cipher)) { case NID_aes_128_cbc: if (!ivcipher) ivcipher = EVP_aes_128_ecb(); /* fall through */ case NID_aes_192_cbc: if (!ivcipher) ivcipher = EVP_aes_192_ecb(); /* fall through */ case NID_aes_256_cbc: if (!ivcipher) ivcipher = EVP_aes_256_ecb(); /* For AES decryption the IV is not needed, * so we always set it to the encryption IV=E(K_Enc, SSC) */ r = encode_ssc(ssc, ctx, &ssc_buf); if (r < 0) goto err; sscbuf = BUF_MEM_create_init(ssc_buf, r); if (!sscbuf) goto err; oldcipher = ctx->cipher; ctx->cipher = ivcipher; ivbuf = cipher_no_pad(ctx, cipher_ctx, ctx->k_enc, sscbuf, 1); ctx->cipher = oldcipher; if (!ivbuf) goto err; p = OPENSSL_realloc(ctx->iv, ivbuf->length); if (!p) goto err; ctx->iv = p; /* Flawfinder: ignore */ memcpy(ctx->iv, ivbuf->data, ivbuf->length); break; case NID_des_ede_cbc: /* For 3DES encryption or decryption the IV is always NULL */ if (ctx->iv) OPENSSL_free(ctx->iv); ctx->iv = NULL; break; default: log_err("Unknown cipher"); goto err; } r = 1; err: if (ssc_buf) OPENSSL_free(ssc_buf); if (sscbuf) BUF_MEM_free(sscbuf); if (ivbuf) BUF_MEM_free(ivbuf); return r; }
int dh_im_compute_key(PACE_CTX * ctx, const BUF_MEM * s, const BUF_MEM * in, BN_CTX *bn_ctx) { int ret = 0; BUF_MEM * x_mem = NULL; BIGNUM * x_bn = NULL, *a = NULL, *p_1 = NULL, *q = NULL; DH *static_key = NULL, *ephemeral_key = NULL; check((ctx && in && ctx->ka_ctx), "Invalid arguments"); if (in->length < (size_t) EVP_CIPHER_key_length(ctx->ka_ctx->cipher) || !ctx->static_key) goto err; BN_CTX_start(bn_ctx); static_key = EVP_PKEY_get1_DH(ctx->static_key); if (!static_key) goto err; /* Initialize ephemeral parameters with parameters from the static key */ ephemeral_key = DHparams_dup_with_q(static_key); if (!ephemeral_key) goto err; /* Perform the actual mapping */ x_mem = cipher_no_pad(ctx->ka_ctx, NULL, in, s, 1); if (!x_mem) goto err; x_bn = BN_bin2bn((unsigned char *) x_mem->data, x_mem->length, x_bn); a = BN_CTX_get(bn_ctx); q = DH_get_q(static_key, bn_ctx); p_1 = BN_dup(static_key->p); if (!x_bn || !a || !q || !p_1 || /* p_1 = p-1 */ !BN_sub_word(p_1, 1) || /* a = p-1 / q */ !BN_div(a, NULL, p_1, q, bn_ctx) || /* g~ = x^a mod p */ !BN_mod_exp(ephemeral_key->g, x_bn, a, static_key->p, bn_ctx)) goto err; /* check if g~ != 1 */ check((!BN_is_one(ephemeral_key->g)), "Bad DH generator"); /* Copy ephemeral key to context structure */ if (!EVP_PKEY_set1_DH(ctx->ka_ctx->key, ephemeral_key)) goto err; ret = 1; err: if (q) BN_clear_free(q); if (p_1) BN_clear_free(p_1); if (x_bn) BN_clear_free(x_bn); if (x_mem) BUF_MEM_free(x_mem); /* Decrement reference count, keys are still available via PACE_CTX */ if (static_key) DH_free(static_key); if (ephemeral_key) DH_free(ephemeral_key); BN_CTX_end(bn_ctx); return ret; }