int ssh_dss_sign(const Key *key, u_char **sigp, u_int *lenp, const u_char *data, u_int datalen) { const int datafellows = CoreConnection::current () .datafellows (); DSA_SIG *sig; const EVP_MD *evp_md = EVP_sha1(); EVP_MD_CTX md; u_char digest[EVP_MAX_MD_SIZE], sigblob[SIGBLOB_LEN]; u_int rlen, slen, len, dlen; Buffer b; if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) { error("ssh_dss_sign: no DSA key"); return -1; } EVP_DigestInit(&md, evp_md); EVP_DigestUpdate(&md, data, datalen); EVP_DigestFinal(&md, digest, &dlen); sig = DSA_do_sign(digest, dlen, key->dsa); memset(digest, 'd', sizeof(digest)); if (sig == NULL) { error("ssh_dss_sign: sign failed"); return -1; } rlen = BN_num_bytes(sig->r); slen = BN_num_bytes(sig->s); if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) { error("bad sig size %u %u", rlen, slen); DSA_SIG_free(sig); return -1; } memset(sigblob, 0, SIGBLOB_LEN); BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen); BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen); DSA_SIG_free(sig); if (datafellows & SSH_BUG_SIGBLOB) { if (lenp != NULL) *lenp = SIGBLOB_LEN; if (sigp != NULL) { *sigp = (u_char*) xmalloc(SIGBLOB_LEN); memcpy(*sigp, sigblob, SIGBLOB_LEN); } } else { /* ietf-drafts */ buffer_init(&b); buffer_put_cstring(&b, "ssh-dss"); buffer_put_string(&b, sigblob, SIGBLOB_LEN); len = buffer_len(&b); if (lenp != NULL) *lenp = len; if (sigp != NULL) { *sigp = (u_char*) xmalloc(len); memcpy(*sigp, buffer_ptr(&b), len); } buffer_free(&b); } return 0; }
int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t len) { return EVP_DigestUpdate(ctx, data, len); }
int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md, const unsigned char *salt, const unsigned char *data, int datal, int count, unsigned char *key, unsigned char *iv) { EVP_MD_CTX c; unsigned char md_buf[EVP_MAX_MD_SIZE]; int niv, nkey, addmd = 0; unsigned int mds = 0, i; int rv = 0; nkey = type->key_len; niv = type->iv_len; OPENSSL_assert(nkey <= EVP_MAX_KEY_LENGTH); OPENSSL_assert(niv <= EVP_MAX_IV_LENGTH); if (data == NULL) return (nkey); EVP_MD_CTX_init(&c); for (;;) { if (!EVP_DigestInit_ex(&c, md, NULL)) goto err; if (addmd++) if (!EVP_DigestUpdate(&c, &(md_buf[0]), mds)) goto err; if (!EVP_DigestUpdate(&c, data, datal)) goto err; if (salt != NULL) if (!EVP_DigestUpdate(&c, salt, PKCS5_SALT_LEN)) goto err; if (!EVP_DigestFinal_ex(&c, &(md_buf[0]), &mds)) goto err; for (i = 1; i < (unsigned int)count; i++) { if (!EVP_DigestInit_ex(&c, md, NULL)) goto err; if (!EVP_DigestUpdate(&c, &(md_buf[0]), mds)) goto err; if (!EVP_DigestFinal_ex(&c, &(md_buf[0]), &mds)) goto err; } i = 0; if (nkey) { for (;;) { if (nkey == 0) break; if (i == mds) break; if (key != NULL) *(key++) = md_buf[i]; nkey--; i++; } } if (niv && (i != mds)) { for (;;) { if (niv == 0) break; if (i == mds) break; if (iv != NULL) *(iv++) = md_buf[i]; niv--; i++; } } if ((nkey == 0) && (niv == 0)) break; } rv = type->key_len; err: EVP_MD_CTX_cleanup(&c); OPENSSL_cleanse(md_buf, sizeof(md_buf)); return rv; }
void DigestEngine::updateImpl(const void* data, std::size_t length) { EVP_DigestUpdate(_pContext, data, length); }
SM2_CIPHERTEXT_VALUE *SM2_do_encrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md, const unsigned char *in, size_t inlen, EC_KEY *ec_key) { int ok = 0; SM2_CIPHERTEXT_VALUE *cv = NULL; const EC_GROUP *ec_group = EC_KEY_get0_group(ec_key); const EC_POINT *pub_key = EC_KEY_get0_public_key(ec_key); KDF_FUNC kdf = KDF_get_x9_63(kdf_md); EC_POINT *point = NULL; BIGNUM *n = NULL; BIGNUM *h = NULL; BIGNUM *k = NULL; BN_CTX *bn_ctx = NULL; EVP_MD_CTX *md_ctx = NULL; unsigned char buf[(OPENSSL_ECC_MAX_FIELD_BITS + 7)/4 + 1]; int nbytes; size_t len; int i; if (!ec_group || !pub_key) { goto end; } if (!kdf) { goto end; } /* init ciphertext_value */ if (!(cv = OPENSSL_malloc(sizeof(SM2_CIPHERTEXT_VALUE)))) { goto end; } bzero(cv, sizeof(SM2_CIPHERTEXT_VALUE)); cv->ephem_point = EC_POINT_new(ec_group); cv->ciphertext = OPENSSL_malloc(inlen); cv->ciphertext_size = inlen; if (!cv->ephem_point || !cv->ciphertext) { goto end; } point = EC_POINT_new(ec_group); n = BN_new(); h = BN_new(); k = BN_new(); bn_ctx = BN_CTX_new(); md_ctx = EVP_MD_CTX_create(); if (!point || !n || !h || !k || !bn_ctx || !md_ctx) { goto end; } /* init ec domain parameters */ if (!EC_GROUP_get_order(ec_group, n, bn_ctx)) { goto end; } if (!EC_GROUP_get_cofactor(ec_group, h, bn_ctx)) { goto end; } nbytes = (EC_GROUP_get_degree(ec_group) + 7) / 8; //OPENSSL_assert(nbytes == BN_num_bytes(n)); #if 0 /* check sm2 curve and md is 256 bits */ OPENSSL_assert(nbytes == 32); OPENSSL_assert(EVP_MD_size(kdf_md) == 32); OPENSSL_assert(EVP_MD_size(mac_md) == 32); #endif do { /* A1: rand k in [1, n-1] */ do { BN_rand_range(k, n); } while (BN_is_zero(k)); /* A2: C1 = [k]G = (x1, y1) */ if (!EC_POINT_mul(ec_group, cv->ephem_point, k, NULL, NULL, bn_ctx)) { goto end; } /* A3: check [h]P_B != O */ if (!EC_POINT_mul(ec_group, point, NULL, pub_key, h, bn_ctx)) { goto end; } if (EC_POINT_is_at_infinity(ec_group, point)) { goto end; } /* A4: compute ECDH [k]P_B = (x2, y2) */ if (!EC_POINT_mul(ec_group, point, NULL, pub_key, k, bn_ctx)) { goto end; } if (!(len = EC_POINT_point2oct(ec_group, point, POINT_CONVERSION_UNCOMPRESSED, buf, sizeof(buf), bn_ctx))) { goto end; } OPENSSL_assert(len == nbytes * 2 + 1); /* A5: t = KDF(x2 || y2, klen) */ kdf(buf + 1, len - 1, cv->ciphertext, &cv->ciphertext_size); for (i = 0; i < cv->ciphertext_size; i++) { if (cv->ciphertext[i]) { break; } } if (i == cv->ciphertext_size) { continue; } break; } while (1); /* A6: C2 = M xor t */ for (i = 0; i < inlen; i++) { cv->ciphertext[i] ^= in[i]; } /* A7: C3 = Hash(x2 || M || y2) */ if (!EVP_DigestInit_ex(md_ctx, mac_md, NULL)) { goto end; } if (!EVP_DigestUpdate(md_ctx, buf + 1, nbytes)) { goto end; } if (!EVP_DigestUpdate(md_ctx, in, inlen)) { goto end; } if (!EVP_DigestUpdate(md_ctx, buf + 1 + nbytes, nbytes)) { goto end; } if (!EVP_DigestFinal_ex(md_ctx, cv->mactag, &cv->mactag_size)) { goto end; } ok = 1; end: if (!ok && cv) { SM2_CIPHERTEXT_VALUE_free(cv); cv = NULL; } if (point) EC_POINT_free(point); if (n) BN_free(n); if (h) BN_free(h); if (k) BN_free(k); if (bn_ctx) BN_CTX_free(bn_ctx); if (md_ctx) EVP_MD_CTX_destroy(md_ctx); return cv; }
int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md, ENGINE *impl) { int i, j, reset = 0; unsigned char pad[HMAC_MAX_MD_CBLOCK]; /* If we are changing MD then we must have a key */ if (md != NULL && md != ctx->md && (key == NULL || len < 0)) return 0; if (md != NULL) { reset = 1; ctx->md = md; } else if (ctx->md) { md = ctx->md; } else { return 0; } if (key != NULL) { reset = 1; j = EVP_MD_block_size(md); OPENSSL_assert(j <= (int)sizeof(ctx->key)); if (j < len) { if (!EVP_DigestInit_ex(ctx->md_ctx, md, impl)) goto err; if (!EVP_DigestUpdate(ctx->md_ctx, key, len)) goto err; if (!EVP_DigestFinal_ex(ctx->md_ctx, ctx->key, &ctx->key_length)) goto err; } else { if (len < 0 || len > (int)sizeof(ctx->key)) return 0; memcpy(ctx->key, key, len); ctx->key_length = len; } if (ctx->key_length != HMAC_MAX_MD_CBLOCK) memset(&ctx->key[ctx->key_length], 0, HMAC_MAX_MD_CBLOCK - ctx->key_length); } if (reset) { for (i = 0; i < HMAC_MAX_MD_CBLOCK; i++) pad[i] = 0x36 ^ ctx->key[i]; if (!EVP_DigestInit_ex(ctx->i_ctx, md, impl)) goto err; if (!EVP_DigestUpdate(ctx->i_ctx, pad, EVP_MD_block_size(md))) goto err; for (i = 0; i < HMAC_MAX_MD_CBLOCK; i++) pad[i] = 0x5c ^ ctx->key[i]; if (!EVP_DigestInit_ex(ctx->o_ctx, md, impl)) goto err; if (!EVP_DigestUpdate(ctx->o_ctx, pad, EVP_MD_block_size(md))) goto err; } if (!EVP_MD_CTX_copy_ex(ctx->md_ctx, ctx->i_ctx)) goto err; return 1; err: return 0; }
/*******************************************************************-o-****** * generate_Ku * * Parameters: * *hashtype MIB OID for the transform type for hashing. * hashtype_len Length of OID value. * *P Pre-allocated bytes of passpharase. * pplen Length of passphrase. * *Ku Buffer to contain Ku. * *kulen Length of Ku buffer. * * Returns: * SNMPERR_SUCCESS Success. * SNMPERR_GENERR All errors. * * * Convert a passphrase into a master user key, Ku, according to the * algorithm given in RFC 2274 concerning the SNMPv3 User Security Model (USM) * as follows: * * Expand the passphrase to fill the passphrase buffer space, if necessary, * concatenation as many duplicates as possible of P to itself. If P is * larger than the buffer space, truncate it to fit. * * Then hash the result with the given hashtype transform. Return * the result as Ku. * * If successful, kulen contains the size of the hash written to Ku. * * NOTE Passphrases less than USM_LENGTH_P_MIN characters in length * cause an error to be returned. * (Punt this check to the cmdline apps? XXX) */ int generate_Ku( oid *hashtype, u_int hashtype_len, u_char *P, size_t pplen, u_char *Ku, size_t *kulen) #if defined(USE_INTERNAL_MD5) || defined(USE_OPENSSL) { int rval = SNMPERR_SUCCESS, nbytes = USM_LENGTH_EXPANDED_PASSPHRASE; u_int i, pindex = 0; u_char buf[USM_LENGTH_KU_HASHBLOCK], *bufp; #ifdef USE_OPENSSL EVP_MD_CTX *ctx = malloc(sizeof(EVP_MD_CTX)); #else MDstruct MD; #endif /* * Sanity check. */ if ( !hashtype || !P || !Ku || !kulen || (*kulen<=0) || (hashtype_len != USM_LENGTH_OID_TRANSFORM) ) { QUITFUN(SNMPERR_GENERR, generate_Ku_quit); } if (pplen < USM_LENGTH_P_MIN) { #ifdef SNMP_TESTING_CODE snmp_log(LOG_WARNING, "Warning: passphrase chosen is below the length requiremnts of the USM.\n"); #else snmp_set_detail("Password length too short."); QUITFUN(SNMPERR_GENERR, generate_Ku_quit); #endif } /* * Setup for the transform type. */ #ifdef USE_OPENSSL if (ISTRANSFORM(hashtype, HMACMD5Auth)) EVP_DigestInit(ctx, EVP_md5()); else if (ISTRANSFORM(hashtype, HMACSHA1Auth)) EVP_DigestInit(ctx, EVP_sha1()); else { free(ctx); return (SNMPERR_GENERR); } #else MDbegin(&MD); #endif /* USE_OPENSSL */ while (nbytes > 0) { bufp = buf; for (i = 0; i < USM_LENGTH_KU_HASHBLOCK; i++) { *bufp++ = P[pindex++ % pplen]; } #ifdef USE_OPENSSL EVP_DigestUpdate(ctx, buf, USM_LENGTH_KU_HASHBLOCK); #else if (MDupdate(&MD, buf, USM_LENGTH_KU_HASHBLOCK*8)) { rval = SNMPERR_USM_ENCRYPTIONERROR; goto md5_fin; } #endif /* USE_OPENSSL */ nbytes -= USM_LENGTH_KU_HASHBLOCK; } #ifdef USE_OPENSSL EVP_DigestFinal(ctx, (unsigned char *) Ku, (unsigned int *) kulen); /* what about free() */ #else if (MDupdate(&MD, buf, 0)) { rval = SNMPERR_USM_ENCRYPTIONERROR; goto md5_fin; } *kulen = sc_get_properlength(hashtype, hashtype_len); MDget(&MD, Ku, *kulen); md5_fin: memset(&MD, 0, sizeof(MD)); #endif /* USE_OPENSSL */ #ifdef SNMP_TESTING_CODE DEBUGMSGTL(("generate_Ku", "generating Ku (from %s): ", P)); for(i=0; i < *kulen; i++) DEBUGMSG(("generate_Ku", "%02x",Ku[i])); DEBUGMSG(("generate_Ku","\n")); #endif /* SNMP_TESTING_CODE */ generate_Ku_quit: memset(buf, 0, sizeof(buf)); #ifdef USE_OPENSSL free(ctx); #endif return rval; } /* end generate_Ku() */
int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt, int saltlen, int id, int iter, int n, unsigned char *out, const EVP_MD *md_type) { unsigned char *B = NULL, *D = NULL, *I = NULL, *p = NULL, *Ai = NULL; int Slen, Plen, Ilen, Ijlen; int i, j, u, v; int ret = 0; BIGNUM *Ij = NULL, *Bpl1 = NULL; /* These hold Ij and B + 1 */ EVP_MD_CTX *ctx = NULL; #ifdef DEBUG_KEYGEN unsigned char *tmpout = out; int tmpn = n; #endif ctx = EVP_MD_CTX_new(); if (ctx == NULL) goto err; #ifdef DEBUG_KEYGEN fprintf(stderr, "KEYGEN DEBUG\n"); fprintf(stderr, "ID %d, ITER %d\n", id, iter); fprintf(stderr, "Password (length %d):\n", passlen); h__dump(pass, passlen); fprintf(stderr, "Salt (length %d):\n", saltlen); h__dump(salt, saltlen); #endif v = EVP_MD_block_size(md_type); u = EVP_MD_size(md_type); if (u < 0) return 0; D = OPENSSL_malloc(v); Ai = OPENSSL_malloc(u); B = OPENSSL_malloc(v + 1); Slen = v * ((saltlen + v - 1) / v); if (passlen) Plen = v * ((passlen + v - 1) / v); else Plen = 0; Ilen = Slen + Plen; I = OPENSSL_malloc(Ilen); Ij = BN_new(); Bpl1 = BN_new(); if (D == NULL || Ai == NULL || B == NULL || I == NULL || Ij == NULL || Bpl1 == NULL) goto err; for (i = 0; i < v; i++) D[i] = id; p = I; for (i = 0; i < Slen; i++) *p++ = salt[i % saltlen]; for (i = 0; i < Plen; i++) *p++ = pass[i % passlen]; for (;;) { if (!EVP_DigestInit_ex(ctx, md_type, NULL) || !EVP_DigestUpdate(ctx, D, v) || !EVP_DigestUpdate(ctx, I, Ilen) || !EVP_DigestFinal_ex(ctx, Ai, NULL)) goto err; for (j = 1; j < iter; j++) { if (!EVP_DigestInit_ex(ctx, md_type, NULL) || !EVP_DigestUpdate(ctx, Ai, u) || !EVP_DigestFinal_ex(ctx, Ai, NULL)) goto err; } memcpy(out, Ai, min(n, u)); if (u >= n) { #ifdef DEBUG_KEYGEN fprintf(stderr, "Output KEY (length %d)\n", tmpn); h__dump(tmpout, tmpn); #endif ret = 1; goto end; } n -= u; out += u; for (j = 0; j < v; j++) B[j] = Ai[j % u]; /* Work out B + 1 first then can use B as tmp space */ if (!BN_bin2bn(B, v, Bpl1)) goto err; if (!BN_add_word(Bpl1, 1)) goto err; for (j = 0; j < Ilen; j += v) { if (!BN_bin2bn(I + j, v, Ij)) goto err; if (!BN_add(Ij, Ij, Bpl1)) goto err; if (!BN_bn2bin(Ij, B)) goto err; Ijlen = BN_num_bytes(Ij); /* If more than 2^(v*8) - 1 cut off MSB */ if (Ijlen > v) { if (!BN_bn2bin(Ij, B)) goto err; memcpy(I + j, B + 1, v); #ifndef PKCS12_BROKEN_KEYGEN /* If less than v bytes pad with zeroes */ } else if (Ijlen < v) { memset(I + j, 0, v - Ijlen); if (!BN_bn2bin(Ij, I + j + v - Ijlen)) goto err; #endif } else if (!BN_bn2bin(Ij, I + j)) goto err; } } err: PKCS12err(PKCS12_F_PKCS12_KEY_GEN_UNI, ERR_R_MALLOC_FAILURE); end: OPENSSL_free(Ai); OPENSSL_free(B); OPENSSL_free(D); OPENSSL_free(I); BN_free(Ij); BN_free(Bpl1); EVP_MD_CTX_free(ctx); return ret; }
int EVP_tls_cbc_digest_record(const EVP_MD *md, uint8_t *md_out, size_t *md_out_size, const uint8_t header[13], const uint8_t *data, size_t data_plus_mac_size, size_t data_plus_mac_plus_padding_size, const uint8_t *mac_secret, unsigned mac_secret_length) { union { double align; uint8_t c[sizeof(LARGEST_DIGEST_CTX)]; } md_state; void (*md_final_raw)(void *ctx, uint8_t *md_out); void (*md_transform)(void *ctx, const uint8_t *block); unsigned md_size, md_block_size = 64; unsigned len, max_mac_bytes, num_blocks, num_starting_blocks, k, mac_end_offset, c, index_a, index_b; unsigned int bits; /* at most 18 bits */ uint8_t length_bytes[MAX_HASH_BIT_COUNT_BYTES]; /* hmac_pad is the masked HMAC key. */ uint8_t hmac_pad[MAX_HASH_BLOCK_SIZE]; uint8_t first_block[MAX_HASH_BLOCK_SIZE]; uint8_t mac_out[EVP_MAX_MD_SIZE]; unsigned i, j, md_out_size_u; EVP_MD_CTX md_ctx; /* mdLengthSize is the number of bytes in the length field that terminates * the hash. */ unsigned md_length_size = 8; /* This is a, hopefully redundant, check that allows us to forget about * many possible overflows later in this function. */ assert(data_plus_mac_plus_padding_size < 1024 * 1024); switch (EVP_MD_type(md)) { case NID_sha1: SHA1_Init((SHA_CTX *)md_state.c); md_final_raw = tls1_sha1_final_raw; md_transform = (void (*)(void *ctx, const uint8_t *block))SHA1_Transform; md_size = 20; break; case NID_sha256: SHA256_Init((SHA256_CTX *)md_state.c); md_final_raw = tls1_sha256_final_raw; md_transform = (void (*)(void *ctx, const uint8_t *block))SHA256_Transform; md_size = 32; break; case NID_sha384: SHA384_Init((SHA512_CTX *)md_state.c); md_final_raw = tls1_sha512_final_raw; md_transform = (void (*)(void *ctx, const uint8_t *block))SHA512_Transform; md_size = 384 / 8; md_block_size = 128; md_length_size = 16; break; default: /* EVP_tls_cbc_record_digest_supported should have been called first to * check that the hash function is supported. */ assert(0); *md_out_size = 0; return 0; } assert(md_length_size <= MAX_HASH_BIT_COUNT_BYTES); assert(md_block_size <= MAX_HASH_BLOCK_SIZE); assert(md_size <= EVP_MAX_MD_SIZE); static const unsigned kHeaderLength = 13; /* kVarianceBlocks is the number of blocks of the hash that we have to * calculate in constant time because they could be altered by the * padding value. * * TLSv1 has MACs up to 48 bytes long (SHA-384) and the padding is not * required to be minimal. Therefore we say that the final six blocks * can vary based on the padding. */ static const unsigned kVarianceBlocks = 6; /* From now on we're dealing with the MAC, which conceptually has 13 * bytes of `header' before the start of the data. */ len = data_plus_mac_plus_padding_size + kHeaderLength; /* max_mac_bytes contains the maximum bytes of bytes in the MAC, including * |header|, assuming that there's no padding. */ max_mac_bytes = len - md_size - 1; /* num_blocks is the maximum number of hash blocks. */ num_blocks = (max_mac_bytes + 1 + md_length_size + md_block_size - 1) / md_block_size; /* In order to calculate the MAC in constant time we have to handle * the final blocks specially because the padding value could cause the * end to appear somewhere in the final |kVarianceBlocks| blocks and we * can't leak where. However, |num_starting_blocks| worth of data can * be hashed right away because no padding value can affect whether * they are plaintext. */ num_starting_blocks = 0; /* k is the starting byte offset into the conceptual header||data where * we start processing. */ k = 0; /* mac_end_offset is the index just past the end of the data to be * MACed. */ mac_end_offset = data_plus_mac_size + kHeaderLength - md_size; /* c is the index of the 0x80 byte in the final hash block that * contains application data. */ c = mac_end_offset % md_block_size; /* index_a is the hash block number that contains the 0x80 terminating * value. */ index_a = mac_end_offset / md_block_size; /* index_b is the hash block number that contains the 64-bit hash * length, in bits. */ index_b = (mac_end_offset + md_length_size) / md_block_size; /* bits is the hash-length in bits. It includes the additional hash * block for the masked HMAC key. */ if (num_blocks > kVarianceBlocks) { num_starting_blocks = num_blocks - kVarianceBlocks; k = md_block_size * num_starting_blocks; } bits = 8 * mac_end_offset; /* Compute the initial HMAC block. */ bits += 8 * md_block_size; memset(hmac_pad, 0, md_block_size); assert(mac_secret_length <= sizeof(hmac_pad)); memcpy(hmac_pad, mac_secret, mac_secret_length); for (i = 0; i < md_block_size; i++) { hmac_pad[i] ^= 0x36; } md_transform(md_state.c, hmac_pad); memset(length_bytes, 0, md_length_size - 4); length_bytes[md_length_size - 4] = (uint8_t)(bits >> 24); length_bytes[md_length_size - 3] = (uint8_t)(bits >> 16); length_bytes[md_length_size - 2] = (uint8_t)(bits >> 8); length_bytes[md_length_size - 1] = (uint8_t)bits; if (k > 0) { /* k is a multiple of md_block_size. */ memcpy(first_block, header, 13); memcpy(first_block + 13, data, md_block_size - 13); md_transform(md_state.c, first_block); for (i = 1; i < k / md_block_size; i++) { md_transform(md_state.c, data + md_block_size * i - 13); } } memset(mac_out, 0, sizeof(mac_out)); /* We now process the final hash blocks. For each block, we construct * it in constant time. If the |i==index_a| then we'll include the 0x80 * bytes and zero pad etc. For each block we selectively copy it, in * constant time, to |mac_out|. */ for (i = num_starting_blocks; i <= num_starting_blocks + kVarianceBlocks; i++) { uint8_t block[MAX_HASH_BLOCK_SIZE]; uint8_t is_block_a = constant_time_eq_8(i, index_a); uint8_t is_block_b = constant_time_eq_8(i, index_b); for (j = 0; j < md_block_size; j++) { uint8_t b = 0, is_past_c, is_past_cp1; if (k < kHeaderLength) { b = header[k]; } else if (k < data_plus_mac_plus_padding_size + kHeaderLength) { b = data[k - kHeaderLength]; } k++; is_past_c = is_block_a & constant_time_ge_8(j, c); is_past_cp1 = is_block_a & constant_time_ge_8(j, c + 1); /* If this is the block containing the end of the * application data, and we are at the offset for the * 0x80 value, then overwrite b with 0x80. */ b = constant_time_select_8(is_past_c, 0x80, b); /* If this the the block containing the end of the * application data and we're past the 0x80 value then * just write zero. */ b = b & ~is_past_cp1; /* If this is index_b (the final block), but not * index_a (the end of the data), then the 64-bit * length didn't fit into index_a and we're having to * add an extra block of zeros. */ b &= ~is_block_b | is_block_a; /* The final bytes of one of the blocks contains the * length. */ if (j >= md_block_size - md_length_size) { /* If this is index_b, write a length byte. */ b = constant_time_select_8( is_block_b, length_bytes[j - (md_block_size - md_length_size)], b); } block[j] = b; } md_transform(md_state.c, block); md_final_raw(md_state.c, block); /* If this is index_b, copy the hash value to |mac_out|. */ for (j = 0; j < md_size; j++) { mac_out[j] |= block[j] & is_block_b; } } EVP_MD_CTX_init(&md_ctx); if (!EVP_DigestInit_ex(&md_ctx, md, NULL /* engine */)) { EVP_MD_CTX_cleanup(&md_ctx); return 0; } /* Complete the HMAC in the standard manner. */ for (i = 0; i < md_block_size; i++) { hmac_pad[i] ^= 0x6a; } EVP_DigestUpdate(&md_ctx, hmac_pad, md_block_size); EVP_DigestUpdate(&md_ctx, mac_out, md_size); EVP_DigestFinal(&md_ctx, md_out, &md_out_size_u); *md_out_size = md_out_size_u; EVP_MD_CTX_cleanup(&md_ctx); return 1; }
krb5_error_code _krb5_pk_octetstring2key(krb5_context context, krb5_enctype type, const void *dhdata, size_t dhsize, const heim_octet_string *c_n, const heim_octet_string *k_n, krb5_keyblock *key) { struct _krb5_encryption_type *et = _krb5_find_enctype(type); krb5_error_code ret; size_t keylen, offset; void *keydata; unsigned char counter; unsigned char shaoutput[SHA_DIGEST_LENGTH]; EVP_MD_CTX *m; if(et == NULL) { krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP, N_("encryption type %d not supported", ""), type); return KRB5_PROG_ETYPE_NOSUPP; } keylen = (et->keytype->bits + 7) / 8; keydata = malloc(keylen); if (keydata == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } m = EVP_MD_CTX_create(); if (m == NULL) { free(keydata); krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } counter = 0; offset = 0; do { EVP_DigestInit_ex(m, EVP_sha1(), NULL); EVP_DigestUpdate(m, &counter, 1); EVP_DigestUpdate(m, dhdata, dhsize); if (c_n) EVP_DigestUpdate(m, c_n->data, c_n->length); if (k_n) EVP_DigestUpdate(m, k_n->data, k_n->length); EVP_DigestFinal_ex(m, shaoutput, NULL); memcpy((unsigned char *)keydata + offset, shaoutput, min(keylen - offset, sizeof(shaoutput))); offset += sizeof(shaoutput); counter++; } while(offset < keylen); memset(shaoutput, 0, sizeof(shaoutput)); EVP_MD_CTX_destroy(m); ret = krb5_random_to_key(context, type, keydata, keylen, key); memset(keydata, 0, sizeof(keylen)); free(keydata); return ret; }
int ssl3_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, int len) { static const unsigned char *salt[3] = { #ifndef CHARSET_EBCDIC (const unsigned char *)"A", (const unsigned char *)"BB", (const unsigned char *)"CCC", #else (const unsigned char *)"\x41", (const unsigned char *)"\x42\x42", (const unsigned char *)"\x43\x43\x43", #endif }; unsigned char buf[EVP_MAX_MD_SIZE]; EVP_MD_CTX *ctx = EVP_MD_CTX_new(); int i, ret = 0; unsigned int n; #ifdef OPENSSL_SSL_TRACE_CRYPTO unsigned char *tmpout = out; #endif if (ctx == NULL) { SSLerr(SSL_F_SSL3_GENERATE_MASTER_SECRET, ERR_R_MALLOC_FAILURE); return 0; } for (i = 0; i < 3; i++) { if (EVP_DigestInit_ex(ctx, s->ctx->sha1, NULL) <= 0 || EVP_DigestUpdate(ctx, salt[i], strlen((const char *)salt[i])) <= 0 || EVP_DigestUpdate(ctx, p, len) <= 0 || EVP_DigestUpdate(ctx, &(s->s3->client_random[0]), SSL3_RANDOM_SIZE) <= 0 || EVP_DigestUpdate(ctx, &(s->s3->server_random[0]), SSL3_RANDOM_SIZE) <= 0 || EVP_DigestFinal_ex(ctx, buf, &n) <= 0 || EVP_DigestInit_ex(ctx, s->ctx->md5, NULL) <= 0 || EVP_DigestUpdate(ctx, p, len) <= 0 || EVP_DigestUpdate(ctx, buf, n) <= 0 || EVP_DigestFinal_ex(ctx, out, &n) <= 0) { SSLerr(SSL_F_SSL3_GENERATE_MASTER_SECRET, ERR_R_INTERNAL_ERROR); ret = 0; break; } out += n; ret += n; } EVP_MD_CTX_free(ctx); #ifdef OPENSSL_SSL_TRACE_CRYPTO if (ret > 0 && s->msg_callback) { s->msg_callback(2, s->version, TLS1_RT_CRYPTO_PREMASTER, p, len, s, s->msg_callback_arg); s->msg_callback(2, s->version, TLS1_RT_CRYPTO_CLIENT_RANDOM, s->s3->client_random, SSL3_RANDOM_SIZE, s, s->msg_callback_arg); s->msg_callback(2, s->version, TLS1_RT_CRYPTO_SERVER_RANDOM, s->s3->server_random, SSL3_RANDOM_SIZE, s, s->msg_callback_arg); s->msg_callback(2, s->version, TLS1_RT_CRYPTO_MASTER, tmpout, SSL3_MASTER_SECRET_SIZE, s, s->msg_callback_arg); } #endif OPENSSL_cleanse(buf, sizeof(buf)); return (ret); }
krb5_error_code _krb5_pk_kdf(krb5_context context, const struct AlgorithmIdentifier *ai, const void *dhdata, size_t dhsize, krb5_const_principal client, krb5_const_principal server, krb5_enctype enctype, const krb5_data *as_req, const krb5_data *pk_as_rep, const Ticket *ticket, krb5_keyblock *key) { struct _krb5_encryption_type *et; krb5_error_code ret; krb5_data other; size_t keylen, offset; uint32_t counter; unsigned char *keydata; unsigned char shaoutput[SHA512_DIGEST_LENGTH]; const EVP_MD *md; EVP_MD_CTX *m; if (der_heim_oid_cmp(&asn1_oid_id_pkinit_kdf_ah_sha1, &ai->algorithm) == 0) { md = EVP_sha1(); } else if (der_heim_oid_cmp(&asn1_oid_id_pkinit_kdf_ah_sha256, &ai->algorithm) == 0) { md = EVP_sha256(); } else if (der_heim_oid_cmp(&asn1_oid_id_pkinit_kdf_ah_sha512, &ai->algorithm) == 0) { md = EVP_sha512(); } else { krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP, N_("KDF not supported", "")); return KRB5_PROG_ETYPE_NOSUPP; } if (ai->parameters != NULL && (ai->parameters->length != 2 || memcmp(ai->parameters->data, "\x05\x00", 2) != 0)) { krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP, N_("kdf params not NULL or the NULL-type", "")); return KRB5_PROG_ETYPE_NOSUPP; } et = _krb5_find_enctype(enctype); if(et == NULL) { krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP, N_("encryption type %d not supported", ""), enctype); return KRB5_PROG_ETYPE_NOSUPP; } keylen = (et->keytype->bits + 7) / 8; keydata = malloc(keylen); if (keydata == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } ret = encode_otherinfo(context, ai, client, server, enctype, as_req, pk_as_rep, ticket, &other); if (ret) { free(keydata); return ret; } m = EVP_MD_CTX_create(); if (m == NULL) { free(keydata); free(other.data); krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } offset = 0; counter = 1; do { unsigned char cdata[4]; EVP_DigestInit_ex(m, md, NULL); _krb5_put_int(cdata, counter, 4); EVP_DigestUpdate(m, cdata, 4); EVP_DigestUpdate(m, dhdata, dhsize); EVP_DigestUpdate(m, other.data, other.length); EVP_DigestFinal_ex(m, shaoutput, NULL); memcpy((unsigned char *)keydata + offset, shaoutput, min(keylen - offset, EVP_MD_CTX_size(m))); offset += EVP_MD_CTX_size(m); counter++; } while(offset < keylen); memset(shaoutput, 0, sizeof(shaoutput)); EVP_MD_CTX_destroy(m); free(other.data); ret = krb5_random_to_key(context, enctype, keydata, keylen, key); memset(keydata, 0, sizeof(keylen)); free(keydata); return ret; }
static isc_result_t opensslrsa_adddata(dst_context_t *dctx, const isc_region_t *data) { #if USE_EVP EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; #endif #ifndef PK11_MD5_DISABLE REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 || dctx->key->key_alg == DST_ALG_RSASHA1 || dctx->key->key_alg == DST_ALG_NSEC3RSASHA1 || dctx->key->key_alg == DST_ALG_RSASHA256 || dctx->key->key_alg == DST_ALG_RSASHA512); #else REQUIRE(dctx->key->key_alg == DST_ALG_RSASHA1 || dctx->key->key_alg == DST_ALG_NSEC3RSASHA1 || dctx->key->key_alg == DST_ALG_RSASHA256 || dctx->key->key_alg == DST_ALG_RSASHA512); #endif #if USE_EVP if (!EVP_DigestUpdate(evp_md_ctx, data->base, data->length)) { return (dst__openssl_toresult3(dctx->category, "EVP_DigestUpdate", ISC_R_FAILURE)); } #else switch (dctx->key->key_alg) { #ifndef PK11_MD5_DISABLE case DST_ALG_RSAMD5: { isc_md5_t *md5ctx = dctx->ctxdata.md5ctx; isc_md5_update(md5ctx, data->base, data->length); } break; #endif case DST_ALG_RSASHA1: case DST_ALG_NSEC3RSASHA1: { isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx; isc_sha1_update(sha1ctx, data->base, data->length); } break; case DST_ALG_RSASHA256: { isc_sha256_t *sha256ctx = dctx->ctxdata.sha256ctx; isc_sha256_update(sha256ctx, data->base, data->length); } break; case DST_ALG_RSASHA512: { isc_sha512_t *sha512ctx = dctx->ctxdata.sha512ctx; isc_sha512_update(sha512ctx, data->base, data->length); } break; default: INSIST(0); } #endif return (ISC_R_SUCCESS); }
int ssh_dss_verify(ncrack_ssh_state *nstate, const Key *key, const u_char *signature, u_int signaturelen, const u_char *data, u_int datalen) { DSA_SIG *sig; const EVP_MD *evp_md = EVP_sha1(); EVP_MD_CTX md; u_char digest[EVP_MAX_MD_SIZE], *sigblob; u_int len, dlen; int rlen, ret; Buffer b; if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) { ssherror("ssh_dss_verify: no DSA key"); return -1; } /* fetch signature */ if (nstate->datafellows & SSH_BUG_SIGBLOB) { sigblob = xmalloc(signaturelen); memcpy(sigblob, signature, signaturelen); len = signaturelen; } else { /* ietf-drafts */ char *ktype; buffer_init(&b); buffer_append(&b, signature, signaturelen); ktype = buffer_get_string(&b, NULL); if (strcmp("ssh-dss", ktype) != 0) { ssherror("ssh_dss_verify: cannot handle type %s", ktype); buffer_free(&b); xfree(ktype); return -1; } xfree(ktype); sigblob = buffer_get_string(&b, &len); rlen = buffer_len(&b); buffer_free(&b); if (rlen != 0) { ssherror("ssh_dss_verify: " "remaining bytes in signature %d", rlen); xfree(sigblob); return -1; } } if (len != SIGBLOB_LEN) { fatal("bad sigbloblen %u != SIGBLOB_LEN", len); } /* parse signature */ if ((sig = DSA_SIG_new()) == NULL) fatal("ssh_dss_verify: DSA_SIG_new failed"); if ((sig->r = BN_new()) == NULL) fatal("ssh_dss_verify: BN_new failed"); if ((sig->s = BN_new()) == NULL) fatal("ssh_dss_verify: BN_new failed"); if ((BN_bin2bn(sigblob, INTBLOB_LEN, sig->r) == NULL) || (BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s) == NULL)) fatal("ssh_dss_verify: BN_bin2bn failed"); /* clean up */ memset(sigblob, 0, len); xfree(sigblob); /* sha1 the data */ EVP_DigestInit(&md, evp_md); EVP_DigestUpdate(&md, data, datalen); EVP_DigestFinal(&md, digest, &dlen); ret = DSA_do_verify(digest, dlen, sig, key->dsa); memset(digest, 'd', sizeof(digest)); DSA_SIG_free(sig); debug("ssh_dss_verify: signature %s", ret == 1 ? "correct" : ret == 0 ? "incorrect" : "error"); return ret; }
bool RarVolume::DecryptRar3Prepare(const uint8 salt[8]) { WString wstr(*m_password); int len = wstr.Length(); if (len == 0) return false; CharBuffer seed(len * 2 + 8); for (int i = 0; i < len; i++) { wchar_t ch = wstr[i]; seed[i * 2] = ch & 0xFF; seed[i * 2 + 1] = (ch & 0xFF00) >> 8; } memcpy(seed + len * 2, salt, 8); debug("seed: %s", *Util::FormatBuffer((const char*)seed, seed.Size())); #ifdef HAVE_OPENSSL EVP_MD_CTX* context = EVP_MD_CTX_create(); if (!EVP_DigestInit(context, EVP_sha1())) { EVP_MD_CTX_destroy(context); return false; } #elif defined(HAVE_NETTLE) sha1_ctx context; sha1_init(&context); #else return false; #endif uint8 digest[20]; const int rounds = 0x40000; for (int i = 0; i < rounds; i++) { #ifdef HAVE_OPENSSL EVP_DigestUpdate(context, *seed, seed.Size()); #elif defined(HAVE_NETTLE) sha1_update(&context, seed.Size(), (const uint8_t*)*seed); #endif uint8 buf[3]; buf[0] = (uint8)i; buf[1] = (uint8)(i >> 8); buf[2] = (uint8)(i >> 16); #ifdef HAVE_OPENSSL EVP_DigestUpdate(context, buf, sizeof(buf)); #elif defined(HAVE_NETTLE) sha1_update(&context, sizeof(buf), buf); #endif if (i % (rounds / 16) == 0) { #ifdef HAVE_OPENSSL EVP_MD_CTX* ivContext = EVP_MD_CTX_create(); EVP_MD_CTX_copy(ivContext, context); EVP_DigestFinal(ivContext, digest, nullptr); EVP_MD_CTX_destroy(ivContext); #elif defined(HAVE_NETTLE) sha1_ctx ivContext = context; sha1_digest(&ivContext, sizeof(digest), digest); #endif m_decryptIV[i / (rounds / 16)] = digest[sizeof(digest) - 1]; } } #ifdef HAVE_OPENSSL EVP_DigestFinal(context, digest, nullptr); EVP_MD_CTX_destroy(context); #elif defined(HAVE_NETTLE) sha1_digest(&context, sizeof(digest), digest); #endif debug("digest: %s", *Util::FormatBuffer((const char*)digest, sizeof(digest))); for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { m_decryptKey[i * 4 + j] = digest[i * 4 + 3 - j]; } } debug("key: %s", *Util::FormatBuffer((const char*)m_decryptKey, sizeof(m_decryptKey))); debug("iv: %s", *Util::FormatBuffer((const char*)m_decryptIV, sizeof(m_decryptIV))); return true; }
int GTDataHash_create(int hash_algorithm, const unsigned char* data, size_t data_length, GTDataHash **data_hash) { int res = GT_UNKNOWN_ERROR; EVP_MD_CTX md_ctx; const EVP_MD *evp_md; GTDataHash *tmp_data_hash = NULL; unsigned char* tmp_hash = NULL; size_t tmp_length; unsigned int digest_length; if ((data == NULL && data_length != 0) || data_hash == NULL) { res = GT_INVALID_ARGUMENT; goto cleanup; } if (!GT_isSupportedHashAlgorithm(hash_algorithm)) { res = GT_UNTRUSTED_HASH_ALGORITHM; goto cleanup; } evp_md = GT_hashChainIDToEVP(hash_algorithm); if (evp_md == NULL) { res = GT_OUT_OF_MEMORY; goto cleanup; } tmp_data_hash = GT_malloc(sizeof(GTDataHash)); if (tmp_data_hash == NULL) { res = GT_OUT_OF_MEMORY; goto cleanup; } tmp_data_hash->digest = NULL; tmp_data_hash->context = NULL; tmp_length = EVP_MD_size(evp_md); tmp_hash = GT_malloc(tmp_length); if (tmp_hash == NULL) { res = GT_OUT_OF_MEMORY; goto cleanup; } EVP_DigestInit(&md_ctx, evp_md); EVP_DigestUpdate(&md_ctx, data, data_length); EVP_DigestFinal(&md_ctx, tmp_hash, &digest_length); assert(digest_length == tmp_length); tmp_data_hash->digest = tmp_hash; tmp_hash = NULL; tmp_data_hash->digest_length = tmp_length; tmp_data_hash->algorithm = hash_algorithm; *data_hash = tmp_data_hash; tmp_data_hash = NULL; res = GT_OK; cleanup: GT_free(tmp_hash); GTDataHash_free(tmp_data_hash); return res; }
int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len) { if (!ctx->md) return 0; return EVP_DigestUpdate(ctx->md_ctx, data, len); }
int PEM_SignUpdate(EVP_MD_CTX *ctx, unsigned char *data, unsigned int count) { return EVP_DigestUpdate(ctx, data, count); }
void write_impl(const char* ptr, size_t size) override { EVP_DigestUpdate(md_ctx, ptr, size); }
int ssl3_change_cipher_state(SSL *s, int which) { unsigned char *p,*key_block,*mac_secret; unsigned char exp_key[EVP_MAX_KEY_LENGTH]; unsigned char exp_iv[EVP_MAX_IV_LENGTH]; unsigned char *ms,*key,*iv,*er1,*er2; EVP_CIPHER_CTX *dd; const EVP_CIPHER *c; #ifndef OPENSSL_NO_COMP COMP_METHOD *comp; #endif const EVP_MD *m; EVP_MD_CTX md; int is_exp,n,i,j,k,cl; int reuse_dd = 0; is_exp=SSL_C_IS_EXPORT(s->s3->tmp.new_cipher); c=s->s3->tmp.new_sym_enc; m=s->s3->tmp.new_hash; #ifndef OPENSSL_NO_COMP if (s->s3->tmp.new_compression == NULL) comp=NULL; else comp=s->s3->tmp.new_compression->method; #endif key_block=s->s3->tmp.key_block; if (which & SSL3_CC_READ) { if (s->enc_read_ctx != NULL) reuse_dd = 1; else if ((s->enc_read_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL) goto err; else /* make sure it's intialized in case we exit later with an error */ EVP_CIPHER_CTX_init(s->enc_read_ctx); dd= s->enc_read_ctx; s->read_hash=m; #ifndef OPENSSL_NO_COMP /* COMPRESS */ if (s->expand != NULL) { COMP_CTX_free(s->expand); s->expand=NULL; } if (comp != NULL) { s->expand=COMP_CTX_new(comp); if (s->expand == NULL) { SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR); goto err2; } if (s->s3->rrec.comp == NULL) s->s3->rrec.comp=(unsigned char *) OPENSSL_malloc(SSL3_RT_MAX_PLAIN_LENGTH); if (s->s3->rrec.comp == NULL) goto err; } #endif memset(&(s->s3->read_sequence[0]),0,8); mac_secret= &(s->s3->read_mac_secret[0]); } else { if (s->enc_write_ctx != NULL) reuse_dd = 1; else if ((s->enc_write_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL) goto err; else /* make sure it's intialized in case we exit later with an error */ EVP_CIPHER_CTX_init(s->enc_write_ctx); dd= s->enc_write_ctx; s->write_hash=m; #ifndef OPENSSL_NO_COMP /* COMPRESS */ if (s->compress != NULL) { COMP_CTX_free(s->compress); s->compress=NULL; } if (comp != NULL) { s->compress=COMP_CTX_new(comp); if (s->compress == NULL) { SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR); goto err2; } } #endif memset(&(s->s3->write_sequence[0]),0,8); mac_secret= &(s->s3->write_mac_secret[0]); } if (reuse_dd) EVP_CIPHER_CTX_cleanup(dd); p=s->s3->tmp.key_block; i=EVP_MD_size(m); cl=EVP_CIPHER_key_length(c); j=is_exp ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ? cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl; /* Was j=(is_exp)?5:EVP_CIPHER_key_length(c); */ k=EVP_CIPHER_iv_length(c); if ( (which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) || (which == SSL3_CHANGE_CIPHER_SERVER_READ)) { ms= &(p[ 0]); n=i+i; key= &(p[ n]); n+=j+j; iv= &(p[ n]); n+=k+k; er1= &(s->s3->client_random[0]); er2= &(s->s3->server_random[0]); } else { n=i; ms= &(p[ n]); n+=i+j; key= &(p[ n]); n+=j+k; iv= &(p[ n]); n+=k; er1= &(s->s3->server_random[0]); er2= &(s->s3->client_random[0]); } if (n > s->s3->tmp.key_block_length) { SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,ERR_R_INTERNAL_ERROR); goto err2; } EVP_MD_CTX_init(&md); memcpy(mac_secret,ms,i); if (is_exp) { /* In here I set both the read and write key/iv to the * same value since only the correct one will be used :-). */ EVP_DigestInit_ex(&md,EVP_md5(), NULL); EVP_DigestUpdate(&md,key,j); EVP_DigestUpdate(&md,er1,SSL3_RANDOM_SIZE); EVP_DigestUpdate(&md,er2,SSL3_RANDOM_SIZE); EVP_DigestFinal_ex(&md,&(exp_key[0]),NULL); key= &(exp_key[0]); if (k > 0) { EVP_DigestInit_ex(&md,EVP_md5(), NULL); EVP_DigestUpdate(&md,er1,SSL3_RANDOM_SIZE); EVP_DigestUpdate(&md,er2,SSL3_RANDOM_SIZE); EVP_DigestFinal_ex(&md,&(exp_iv[0]),NULL); iv= &(exp_iv[0]); } } s->session->key_arg_length=0; EVP_CipherInit_ex(dd,c,NULL,key,iv,(which & SSL3_CC_WRITE)); OPENSSL_cleanse(&(exp_key[0]),sizeof(exp_key)); OPENSSL_cleanse(&(exp_iv[0]),sizeof(exp_iv)); EVP_MD_CTX_cleanup(&md); return(1); err: SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,ERR_R_MALLOC_FAILURE); err2: return(0); }
static OM_uint32 unwrap_des (OM_uint32 * minor_status, const gsskrb5_ctx context_handle, const gss_buffer_t input_message_buffer, gss_buffer_t output_message_buffer, int * conf_state, gss_qop_t * qop_state, krb5_keyblock *key ) { u_char *p, *seq; size_t len; EVP_MD_CTX *md5; u_char hash[16]; EVP_CIPHER_CTX *des_ctx; DES_key_schedule schedule; DES_cblock deskey; DES_cblock zero; size_t i; uint32_t seq_number; size_t padlength; OM_uint32 ret; int cstate; int cmp; int token_len; if (IS_DCE_STYLE(context_handle)) { token_len = 22 + 8 + 15; /* 45 */ } else { token_len = input_message_buffer->length; } p = input_message_buffer->value; ret = _gsskrb5_verify_header (&p, token_len, "\x02\x01", GSS_KRB5_MECHANISM); if (ret) return ret; if (memcmp (p, "\x00\x00", 2) != 0) return GSS_S_BAD_SIG; p += 2; if (memcmp (p, "\x00\x00", 2) == 0) { cstate = 1; } else if (memcmp (p, "\xFF\xFF", 2) == 0) { cstate = 0; } else return GSS_S_BAD_MIC; p += 2; if(conf_state != NULL) *conf_state = cstate; if (memcmp (p, "\xff\xff", 2) != 0) return GSS_S_DEFECTIVE_TOKEN; p += 2; p += 16; len = p - (u_char *)input_message_buffer->value; if(cstate) { /* decrypt data */ memcpy (&deskey, key->keyvalue.data, sizeof(deskey)); memset (&zero, 0, sizeof(zero)); for (i = 0; i < sizeof(deskey); ++i) deskey[i] ^= 0xf0; des_ctx = EVP_CIPHER_CTX_new(); if (des_ctx == NULL) { memset (deskey, 0, sizeof(deskey)); *minor_status = ENOMEM; return GSS_S_FAILURE; } EVP_CipherInit_ex(des_ctx, EVP_des_cbc(), NULL, deskey, zero, 0); EVP_Cipher(des_ctx, p, p, input_message_buffer->length - len); EVP_CIPHER_CTX_free(des_ctx); memset (deskey, 0, sizeof(deskey)); } if (IS_DCE_STYLE(context_handle)) { padlength = 0; } else { /* check pad */ ret = _gssapi_verify_pad(input_message_buffer, input_message_buffer->length - len, &padlength); if (ret) return ret; } md5 = EVP_MD_CTX_create(); EVP_DigestInit_ex(md5, EVP_md5(), NULL); EVP_DigestUpdate(md5, p - 24, 8); EVP_DigestUpdate(md5, p, input_message_buffer->length - len); EVP_DigestFinal_ex(md5, hash, NULL); EVP_MD_CTX_destroy(md5); memset (&zero, 0, sizeof(zero)); memcpy (&deskey, key->keyvalue.data, sizeof(deskey)); DES_set_key_unchecked (&deskey, &schedule); DES_cbc_cksum ((void *)hash, (void *)hash, sizeof(hash), &schedule, &zero); if (ct_memcmp (p - 8, hash, 8) != 0) { memset (deskey, 0, sizeof(deskey)); memset (&schedule, 0, sizeof(schedule)); return GSS_S_BAD_MIC; } /* verify sequence number */ des_ctx = EVP_CIPHER_CTX_new(); if (des_ctx == NULL) { memset (deskey, 0, sizeof(deskey)); memset (&schedule, 0, sizeof(schedule)); *minor_status = ENOMEM; return GSS_S_FAILURE; } HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); p -= 16; EVP_CipherInit_ex(des_ctx, EVP_des_cbc(), NULL, key->keyvalue.data, hash, 0); EVP_Cipher(des_ctx, p, p, 8); EVP_CIPHER_CTX_free(des_ctx); memset (deskey, 0, sizeof(deskey)); memset (&schedule, 0, sizeof(schedule)); seq = p; _gsskrb5_decode_om_uint32(seq, &seq_number); if (context_handle->more_flags & LOCAL) cmp = ct_memcmp(&seq[4], "\xff\xff\xff\xff", 4); else cmp = ct_memcmp(&seq[4], "\x00\x00\x00\x00", 4); if (cmp != 0) { HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); return GSS_S_BAD_MIC; } ret = _gssapi_msg_order_check(context_handle->order, seq_number); if (ret) { HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); return ret; } HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); /* copy out data */ output_message_buffer->length = input_message_buffer->length - len - padlength - 8; output_message_buffer->value = malloc(output_message_buffer->length); if(output_message_buffer->length != 0 && output_message_buffer->value == NULL) return GSS_S_FAILURE; memcpy (output_message_buffer->value, p + 24, output_message_buffer->length); return GSS_S_COMPLETE; }
void ssl3_finish_mac(SSL *s, const unsigned char *buf, int len) { EVP_DigestUpdate(&(s->s3->finish_dgst1),buf,len); EVP_DigestUpdate(&(s->s3->finish_dgst2),buf,len); }
void EVP_SignUpdate(EVP_MD_CTX *ctx, unsigned char *data, unsigned int count) { EVP_DigestUpdate(ctx,data,count); }
void module_sha256_update(struct image *image, uint8_t *data, size_t bytes) { EVP_DigestUpdate(image->mdctx, data, bytes); }
int SM2_do_decrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md, const SM2_CIPHERTEXT_VALUE *cv, unsigned char *out, size_t *outlen, EC_KEY *ec_key) { int ret = 0; const EC_GROUP *ec_group = EC_KEY_get0_group(ec_key); const BIGNUM *pri_key = EC_KEY_get0_private_key(ec_key); KDF_FUNC kdf = KDF_get_x9_63(kdf_md); EC_POINT *point = NULL; BIGNUM *n = NULL; BIGNUM *h = NULL; BN_CTX *bn_ctx = NULL; EVP_MD_CTX *md_ctx = NULL; unsigned char buf[(OPENSSL_ECC_MAX_FIELD_BITS + 7)/4 + 1]; unsigned char mac[EVP_MAX_MD_SIZE]; unsigned int maclen; int nbytes; size_t size; int i; OPENSSL_assert(kdf_md && mac_md && cv && ec_key); OPENSSL_assert(cv->ephem_point && cv->ciphertext); if (!ec_group || !pri_key) { goto end; } if (!kdf) { goto end; } if (!out) { *outlen = cv->ciphertext_size; return 1; } if (*outlen < cv->ciphertext_size) { goto end; } /* init vars */ point = EC_POINT_new(ec_group); n = BN_new(); h = BN_new(); bn_ctx = BN_CTX_new(); md_ctx = EVP_MD_CTX_create(); if (!point || !n || !h || !bn_ctx || !md_ctx) { goto end; } /* init ec domain parameters */ if (!EC_GROUP_get_order(ec_group, n, bn_ctx)) { goto end; } if (!EC_GROUP_get_cofactor(ec_group, h, bn_ctx)) { goto end; } nbytes = (EC_GROUP_get_degree(ec_group) + 7) / 8; //OPENSSL_assert(nbytes == BN_num_bytes(n)); #if 0 /* check sm2 curve and md is 256 bits */ OPENSSL_assert(nbytes == 32); OPENSSL_assert(EVP_MD_size(kdf_md) == 32); OPENSSL_assert(EVP_MD_size(mac_md) == 32); #endif /* B2: check [h]C1 != O */ if (!EC_POINT_mul(ec_group, point, NULL, cv->ephem_point, h, bn_ctx)) { goto end; } if (EC_POINT_is_at_infinity(ec_group, point)) { goto end; } /* B3: compute ECDH [d]C1 = (x2, y2) */ if (!EC_POINT_mul(ec_group, point, NULL, cv->ephem_point, pri_key, bn_ctx)) { goto end; } if (!(size = EC_POINT_point2oct(ec_group, point, POINT_CONVERSION_UNCOMPRESSED, buf, sizeof(buf), bn_ctx))) { goto end; } OPENSSL_assert(size == 1 + nbytes * 2); /* B4: compute t = KDF(x2 || y2, clen) */ *outlen = cv->ciphertext_size; //FIXME: duplicated code kdf(buf + 1, size - 1, out, outlen); /* B5: compute M = C2 xor t */ for (i = 0; i < cv->ciphertext_size; i++) { out[i] ^= cv->ciphertext[i]; } *outlen = cv->ciphertext_size; /* B6: check Hash(x2 || M || y2) == C3 */ if (!EVP_DigestInit_ex(md_ctx, mac_md, NULL)) { goto end; } if (!EVP_DigestUpdate(md_ctx, buf + 1, nbytes)) { goto end; } if (!EVP_DigestUpdate(md_ctx, out, *outlen)) { goto end; } if (!EVP_DigestUpdate(md_ctx, buf + 1 + nbytes, nbytes)) { goto end; } if (!EVP_DigestFinal_ex(md_ctx, mac, &maclen)) { goto end; } if (cv->mactag_size != maclen || memcmp(cv->mactag, mac, maclen)) { goto end; } ret = 1; end: if (point) EC_POINT_free(point); if (n) BN_free(n); if (h) BN_free(h); if (bn_ctx) BN_CTX_free(bn_ctx); if (md_ctx) EVP_MD_CTX_destroy(md_ctx); return ret; }
/* Updates the digest context * Returns 1 if successful, 0 on failure or -1 on error */ int digest_context_update( digest_context_t *digest_context, uint8_t *buffer, size_t size, liberror_error_t **error ) { static char *function = "digest_context_update"; if( digest_context == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_ARGUMENTS, LIBERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid digest context.", function ); return( -1 ); } if( buffer == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_ARGUMENTS, LIBERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid buffer.", function ); return( -1 ); } if( size > (size_t) SSIZE_MAX ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_ARGUMENTS, LIBERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid size value exceeds maximum.", function ); return( -1 ); } #if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) if( EVP_DigestUpdate( digest_context, (const void *) buffer, (unsigned long) size ) != 1 ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_RUNTIME, LIBERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to update digest hash.", function ); return( 0 ); } #elif defined( HAVE_WINCPRYPT_H ) if( digest_context->hash == 0 ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_RUNTIME, LIBERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: invalid digest context - missing hash.", function ); return( -1 ); } if( CryptHashData( digest_context->hash, (BYTE *) buffer, (DWORD) size, 0 ) != 1 ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_RUNTIME, LIBERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to update digest context hash.", function ); return( 0 ); } #endif return( 1 ); }
static int SSHKDF(const EVP_MD *evp_md, const unsigned char *key, size_t key_len, const unsigned char *xcghash, size_t xcghash_len, const unsigned char *session_id, size_t session_id_len, char type, unsigned char *okey, size_t okey_len) { EVP_MD_CTX *md = NULL; unsigned char digest[EVP_MAX_MD_SIZE]; unsigned int dsize = 0; size_t cursize = 0; int ret = 0; md = EVP_MD_CTX_new(); if (md == NULL) return 0; if (!EVP_DigestInit_ex(md, evp_md, NULL)) goto out; if (!EVP_DigestUpdate(md, key, key_len)) goto out; if (!EVP_DigestUpdate(md, xcghash, xcghash_len)) goto out; if (!EVP_DigestUpdate(md, &type, 1)) goto out; if (!EVP_DigestUpdate(md, session_id, session_id_len)) goto out; if (!EVP_DigestFinal_ex(md, digest, &dsize)) goto out; if (okey_len < dsize) { memcpy(okey, digest, okey_len); ret = 1; goto out; } memcpy(okey, digest, dsize); for (cursize = dsize; cursize < okey_len; cursize += dsize) { if (!EVP_DigestInit_ex(md, evp_md, NULL)) goto out; if (!EVP_DigestUpdate(md, key, key_len)) goto out; if (!EVP_DigestUpdate(md, xcghash, xcghash_len)) goto out; if (!EVP_DigestUpdate(md, okey, cursize)) goto out; if (!EVP_DigestFinal_ex(md, digest, &dsize)) goto out; if (okey_len < cursize + dsize) { memcpy(okey + cursize, digest, okey_len - cursize); ret = 1; goto out; } memcpy(okey + cursize, digest, dsize); } ret = 1; out: EVP_MD_CTX_free(md); OPENSSL_cleanse(digest, EVP_MAX_MD_SIZE); return ret; }
_SCAPI_NOT_CONFIGURED #endif /* */ /* * sc_hash(): a generic wrapper around whatever hashing package we are using. * * IN: * hashtype - oid pointer to a hash type * hashtypelen - length of oid pointer * buf - u_char buffer to be hashed * buf_len - integer length of buf data * MAC_len - length of the passed MAC buffer size. * * OUT: * MAC - pre-malloced space to store hash output. * MAC_len - length of MAC output to the MAC buffer. * * Returns: * SNMPERR_SUCCESS Success. * SNMP_SC_GENERAL_FAILURE Any error. */ int sc_hash(const oid * hashtype, size_t hashtypelen, u_char * buf, size_t buf_len, u_char * MAC, size_t * MAC_len) #if defined(USE_INTERNAL_MD5) || defined(USE_OPENSSL) { #ifdef USE_OPENSSL int rval = SNMPERR_SUCCESS; const EVP_MD *hashfn; EVP_MD_CTX ctx, *cptr; #endif DEBUGTRACE; if (hashtype == NULL || hashtypelen < 0 || buf == NULL || buf_len < 0 || MAC == NULL || MAC_len == NULL || (int) (*MAC_len) < sc_get_properlength(hashtype, hashtypelen)) return (SNMPERR_GENERR); #ifdef USE_OPENSSL /* * Determine transform type. */ if (ISTRANSFORM(hashtype, HMACMD5Auth)) { hashfn = (const EVP_MD *) EVP_md5(); } else if (ISTRANSFORM(hashtype, HMACSHA1Auth)) { hashfn = (const EVP_MD *) EVP_sha1(); } else { return (SNMPERR_GENERR); } /** initialize the pointer */ memset(&ctx, 0, sizeof(ctx)); cptr = &ctx; #if defined(OLD_DES) EVP_DigestInit(cptr, hashfn); #else /* !OLD_DES */ /* this is needed if the runtime library is different than the compiled library since the openssl versions are very different. */ if (SSLeay() < 0x907000) { /* the old version of the struct was bigger and thus more memory is needed. should be 152, but we use 256 for safety. */ cptr = malloc(256); EVP_DigestInit(cptr, hashfn); } else { EVP_MD_CTX_init(cptr); EVP_DigestInit(cptr, hashfn); } #endif /** pass the data */ EVP_DigestUpdate(cptr, buf, buf_len); /** do the final pass */ #if defined(OLD_DES) EVP_DigestFinal(cptr, MAC, MAC_len); #else /* !OLD_DES */ if (SSLeay() < 0x907000) { EVP_DigestFinal(cptr, MAC, MAC_len); free(cptr); } else { EVP_DigestFinal_ex(cptr, MAC, MAC_len); EVP_MD_CTX_cleanup(cptr); } #endif return (rval); #else /* USE_INTERNAL_MD5 */ if (MDchecksum(buf, buf_len, MAC, *MAC_len)) { return SNMPERR_GENERR; } if (*MAC_len > 16) *MAC_len = 16; return SNMPERR_SUCCESS; #endif /* USE_OPENSSL */ }
int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md, ENGINE *impl) { int i, j, reset = 0; unsigned char pad[HMAC_MAX_MD_CBLOCK]; #ifdef OPENSSL_FIPS if (FIPS_mode()) { /* If we have an ENGINE need to allow non FIPS */ if ((impl || ctx->i_ctx.engine) && !(ctx->i_ctx.flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW)) { EVPerr(EVP_F_HMAC_INIT_EX, EVP_R_DISABLED_FOR_FIPS); return 0; } /* * Other algorithm blocking will be done in FIPS_cmac_init, via * FIPS_hmac_init_ex(). */ if (!impl && !ctx->i_ctx.engine) return FIPS_hmac_init_ex(ctx, key, len, md, NULL); } #endif /* If we are changing MD then we must have a key */ if (md != NULL && md != ctx->md && (key == NULL || len < 0)) return 0; if (md != NULL) { reset = 1; ctx->md = md; } else if (ctx->md) { md = ctx->md; } else { return 0; } if (key != NULL) { reset = 1; j = EVP_MD_block_size(md); OPENSSL_assert(j <= (int)sizeof(ctx->key)); if (j < len) { if (!EVP_DigestInit_ex(&ctx->md_ctx, md, impl)) goto err; if (!EVP_DigestUpdate(&ctx->md_ctx, key, len)) goto err; if (!EVP_DigestFinal_ex(&(ctx->md_ctx), ctx->key, &ctx->key_length)) goto err; } else { if (len < 0 || len > (int)sizeof(ctx->key)) return 0; memcpy(ctx->key, key, len); ctx->key_length = len; } if (ctx->key_length != HMAC_MAX_MD_CBLOCK) memset(&ctx->key[ctx->key_length], 0, HMAC_MAX_MD_CBLOCK - ctx->key_length); } if (reset) { for (i = 0; i < HMAC_MAX_MD_CBLOCK; i++) pad[i] = 0x36 ^ ctx->key[i]; if (!EVP_DigestInit_ex(&ctx->i_ctx, md, impl)) goto err; if (!EVP_DigestUpdate(&ctx->i_ctx, pad, EVP_MD_block_size(md))) goto err; for (i = 0; i < HMAC_MAX_MD_CBLOCK; i++) pad[i] = 0x5c ^ ctx->key[i]; if (!EVP_DigestInit_ex(&ctx->o_ctx, md, impl)) goto err; if (!EVP_DigestUpdate(&ctx->o_ctx, pad, EVP_MD_block_size(md))) goto err; } if (!EVP_MD_CTX_copy_ex(&ctx->md_ctx, &ctx->i_ctx)) goto err; return 1; err: return 0; }
char * ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check, const char *data) { Buffer buf; size_t i; int oidpos, enclen; char *mechs, *encoded; u_char digest[EVP_MAX_MD_SIZE]; char deroid[2]; const EVP_MD *evp_md = EVP_md5(); EVP_MD_CTX md; if (gss_enc2oid != NULL) { for (i = 0; gss_enc2oid[i].encoded != NULL; i++) xfree(gss_enc2oid[i].encoded); xfree(gss_enc2oid); } gss_enc2oid = xmalloc(sizeof(ssh_gss_kex_mapping) * (gss_supported->count + 1)); buffer_init(&buf); oidpos = 0; for (i = 0; i < gss_supported->count; i++) { if (gss_supported->elements[i].length < 128 && (*check)(NULL, &(gss_supported->elements[i]), data)) { deroid[0] = SSH_GSS_OIDTYPE; deroid[1] = gss_supported->elements[i].length; EVP_DigestInit(&md, evp_md); EVP_DigestUpdate(&md, deroid, 2); EVP_DigestUpdate(&md, gss_supported->elements[i].elements, gss_supported->elements[i].length); EVP_DigestFinal(&md, digest, NULL); encoded = xmalloc(EVP_MD_size(evp_md) * 2); enclen = __b64_ntop(digest, EVP_MD_size(evp_md), encoded, EVP_MD_size(evp_md) * 2); if (oidpos != 0) buffer_put_char(&buf, ','); buffer_append(&buf, KEX_GSS_GEX_SHA1_ID, sizeof(KEX_GSS_GEX_SHA1_ID) - 1); buffer_append(&buf, encoded, enclen); buffer_put_char(&buf, ','); buffer_append(&buf, KEX_GSS_GRP1_SHA1_ID, sizeof(KEX_GSS_GRP1_SHA1_ID) - 1); buffer_append(&buf, encoded, enclen); buffer_put_char(&buf, ','); buffer_append(&buf, KEX_GSS_GRP14_SHA1_ID, sizeof(KEX_GSS_GRP14_SHA1_ID) - 1); buffer_append(&buf, encoded, enclen); gss_enc2oid[oidpos].oid = &(gss_supported->elements[i]); gss_enc2oid[oidpos].encoded = encoded; oidpos++; } } gss_enc2oid[oidpos].oid = NULL; gss_enc2oid[oidpos].encoded = NULL; buffer_put_char(&buf, '\0'); mechs = xmalloc(buffer_len(&buf)); buffer_get(&buf, mechs, buffer_len(&buf)); buffer_free(&buf); if (strlen(mechs) == 0) { xfree(mechs); mechs = NULL; } return (mechs); }