static int block_out(BIO *b) { BIO_OK_CTX *ctx; EVP_MD_CTX *md; unsigned long tl; const EVP_MD *digest; int md_size; ctx = BIO_get_data(b); md = ctx->md; digest = EVP_MD_CTX_md(md); md_size = EVP_MD_size(digest); tl = ctx->buf_len - OK_BLOCK_BLOCK; ctx->buf[0] = (unsigned char)(tl >> 24); ctx->buf[1] = (unsigned char)(tl >> 16); ctx->buf[2] = (unsigned char)(tl >> 8); ctx->buf[3] = (unsigned char)(tl); if (!EVP_DigestUpdate(md, (unsigned char *)&(ctx->buf[OK_BLOCK_BLOCK]), tl)) goto berr; if (!EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL)) goto berr; ctx->buf_len += md_size; ctx->blockout = 1; return 1; berr: BIO_clear_retry_flags(b); return 0; }
/* * Public */ const EVP_MD * GetDigestPtr(VALUE obj) { const EVP_MD *md; ASN1_OBJECT *oid = NULL; if (RB_TYPE_P(obj, T_STRING)) { const char *name = StringValueCStr(obj); md = EVP_get_digestbyname(name); if (!md) { oid = OBJ_txt2obj(name, 0); md = EVP_get_digestbyobj(oid); ASN1_OBJECT_free(oid); } if(!md) ossl_raise(rb_eRuntimeError, "Unsupported digest algorithm (%"PRIsVALUE").", obj); } else { EVP_MD_CTX *ctx; SafeGetDigest(obj, ctx); md = EVP_MD_CTX_md(ctx); } return md; }
int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain, X509_ALGOR *mdalg) { int nid; ASN1_OBJECT *mdoid; X509_ALGOR_get0(&mdoid, NULL, NULL, mdalg); nid = OBJ_obj2nid(mdoid); /* Look for digest type to match signature */ for (;;) { EVP_MD_CTX *mtmp; chain = BIO_find_type(chain, BIO_TYPE_MD); if (chain == NULL) { CMSerr(CMS_F_CMS_DIGESTALGORITHM_FIND_CTX, CMS_R_NO_MATCHING_DIGEST); return 0; } BIO_get_md_ctx(chain, &mtmp); if (EVP_MD_CTX_type(mtmp) == nid /* * Workaround for broken implementations that use signature * algorithm OID instead of digest. */ || EVP_MD_pkey_type(EVP_MD_CTX_md(mtmp)) == nid) return EVP_MD_CTX_copy_ex(mctx, mtmp); chain = BIO_next(chain); } }
static int ssl3_handshake_mac(SSL *s, EVP_MD_CTX *in_ctx, const char *sender, int len, unsigned char *p) { unsigned int ret; int npad,n; unsigned int i; unsigned char md_buf[EVP_MAX_MD_SIZE]; EVP_MD_CTX ctx; EVP_MD_CTX_copy(&ctx,in_ctx); n=EVP_MD_CTX_size(&ctx); npad=(48/n)*n; if (sender != NULL) EVP_DigestUpdate(&ctx,sender,len); EVP_DigestUpdate(&ctx,s->session->master_key, s->session->master_key_length); EVP_DigestUpdate(&ctx,ssl3_pad_1,npad); EVP_DigestFinal(&ctx,md_buf,&i); EVP_DigestInit(&ctx,EVP_MD_CTX_md(&ctx)); EVP_DigestUpdate(&ctx,s->session->master_key, s->session->master_key_length); EVP_DigestUpdate(&ctx,ssl3_pad_2,npad); EVP_DigestUpdate(&ctx,md_buf,i); EVP_DigestFinal(&ctx,p,&ret); memset(&ctx,0,sizeof(EVP_MD_CTX)); return((int)ret); }
static int pkey_sm2_ctrl_digestinit(EVP_PKEY_CTX *pk_ctx, EVP_MD_CTX *md_ctx) { int ret; EC_KEY *ec_key = pk_ctx->pkey->pkey.ec; const EVP_MD *md = EVP_MD_CTX_md(md_ctx); char *id; unsigned char zid[EVP_MAX_MD_SIZE]; unsigned int zidlen = sizeof(zid); if (!(id = SM2_get_id(ec_key))) { return 0; } //FIXME: check this function if (!SM2_compute_id_digest(zid, &zidlen, md, id, strlen(zidlen), ec_key)) { return 0; } if (!EVP_DigestInit_ex(md_ctx, md, NULL)) { goto end; } if (!EVP_DigestUpdate(md_ctx, zid, zidlen)) { goto end; } EVP_MD_CTX_set_flags(md_ctx, EVP_MD_CTX_FLAG_NO_INIT); end: return ret; }
static int ssl3_handshake_mac(SSL *s, EVP_MD_CTX *in_ctx, const char *sender, int len, unsigned char *p) { unsigned int ret; int npad,n; unsigned int i; unsigned char md_buf[EVP_MAX_MD_SIZE]; EVP_MD_CTX ctx; EVP_MD_CTX_init(&ctx); EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); EVP_MD_CTX_copy_ex(&ctx,in_ctx); n=EVP_MD_CTX_size(&ctx); npad=(48/n)*n; if (sender != NULL) EVP_DigestUpdate(&ctx,sender,len); EVP_DigestUpdate(&ctx,s->session->master_key, s->session->master_key_length); EVP_DigestUpdate(&ctx,ssl3_pad_1,npad); EVP_DigestFinal_ex(&ctx,md_buf,&i); EVP_DigestInit_ex(&ctx,EVP_MD_CTX_md(&ctx), NULL); EVP_DigestUpdate(&ctx,s->session->master_key, s->session->master_key_length); EVP_DigestUpdate(&ctx,ssl3_pad_2,npad); EVP_DigestUpdate(&ctx,md_buf,i); EVP_DigestFinal_ex(&ctx,p,&ret); EVP_MD_CTX_cleanup(&ctx); return((int)ret); }
/** @impl_interface_method{RTCRDIGESTDESC::pfnInit} */ static DECLCALLBACK(int) rtCrDigestOsslEvp_Init(void *pvState, void *pvOpaque, bool fReInit) { EVP_MD_CTX *pThis = (EVP_MD_CTX *)pvState; EVP_MD const *pEvpType = (EVP_MD const *)pvOpaque; if (fReInit) { pEvpType = EVP_MD_CTX_md(pThis); # if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER) EVP_MD_CTX_reset(pThis); # else EVP_MD_CTX_cleanup(pThis); # endif } AssertPtrReturn(pEvpType, VERR_INVALID_PARAMETER); # if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER) Assert(EVP_MD_block_size(pEvpType)); # else Assert(pEvpType->md_size); # endif if (EVP_DigestInit(pThis, pEvpType)) return VINF_SUCCESS; return VERR_CR_DIGEST_OSSL_DIGEST_INIT_ERROR; }
static int evp_reset(lua_State *L) { EVP_MD_CTX *c = evp_pget(L, 1); const EVP_MD *t = EVP_MD_CTX_md(c); EVP_MD_CTX_cleanup(c); EVP_MD_CTX_init(c); EVP_DigestInit_ex(c, t, NULL); return 0; }
/* * call-seq: * digest.name -> string * * Returns the sn of this Digest instance. * * === Example * digest = OpenSSL::Digest::SHA512.new * puts digest.name # => SHA512 * */ static VALUE ossl_digest_name(VALUE self) { EVP_MD_CTX *ctx; GetDigest(self, ctx); return rb_str_new2(EVP_MD_name(EVP_MD_CTX_md(ctx))); }
/* * call-seq: * digest.reset -> self * */ static VALUE ossl_digest_reset(VALUE self, SEL sel) { EVP_MD_CTX *ctx; GetDigest(self, ctx); EVP_DigestInit_ex(ctx, EVP_MD_CTX_md(ctx), NULL); return self; }
static void digest_reset(PX_MD * h) { EVP_MD_CTX *ctx = (EVP_MD_CTX *) h->p.ptr; const EVP_MD *md; md = EVP_MD_CTX_md(ctx); EVP_DigestInit(ctx, md); }
static mrb_value lib_md_digest_bang(mrb_state *mrb, struct mrb_md *md) { unsigned int mdlen; unsigned char mdstr[EVP_MAX_MD_SIZE]; EVP_DigestFinal_ex(md->ctx, mdstr, &mdlen); EVP_DigestInit_ex(md->ctx, EVP_MD_CTX_md(md->ctx), NULL); return mrb_str_new(mrb, (char *)mdstr, mdlen); }
static LUA_FUNCTION(openssl_digest_ctx_info) { EVP_MD_CTX *ctx = CHECK_OBJECT(1, EVP_MD_CTX, "openssl.evp_digest_ctx"); lua_newtable(L); AUXILIAR_SET(L, -1, "block_size", EVP_MD_CTX_block_size(ctx), integer); AUXILIAR_SET(L, -1, "size", EVP_MD_CTX_size(ctx), integer); AUXILIAR_SET(L, -1, "type", EVP_MD_CTX_type(ctx), integer); AUXILIAR_SETOBJECT(L, EVP_MD_CTX_md(ctx), "openssl.evp_digest", -1, "digest"); return 1; }
static int ssl3_handshake_mac(SSL *s, int md_nid, const char *sender, int len, unsigned char *p) { unsigned int ret; int npad, n; unsigned int i; unsigned char md_buf[EVP_MAX_MD_SIZE]; EVP_MD_CTX ctx, *d = NULL; if (!ssl3_digest_cached_records(s, 0)) return 0; /* * Search for digest of specified type in the handshake_dgst array */ for (i = 0; i < SSL_MAX_DIGEST; i++) { if (s->s3->handshake_dgst[i] && EVP_MD_CTX_type(s->s3->handshake_dgst[i]) == md_nid) { d = s->s3->handshake_dgst[i]; break; } } if (!d) { SSLerr(SSL_F_SSL3_HANDSHAKE_MAC, SSL_R_NO_REQUIRED_DIGEST); return 0; } EVP_MD_CTX_init(&ctx); EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); EVP_MD_CTX_copy_ex(&ctx, d); n = EVP_MD_CTX_size(&ctx); if (n < 0) return 0; npad = (48 / n) * n; if ((sender != NULL && EVP_DigestUpdate(&ctx, sender, len) <= 0) || EVP_DigestUpdate(&ctx, s->session->master_key, s->session->master_key_length) <= 0 || EVP_DigestUpdate(&ctx, ssl3_pad_1, npad) <= 0 || EVP_DigestFinal_ex(&ctx, md_buf, &i) <= 0 || EVP_DigestInit_ex(&ctx, EVP_MD_CTX_md(&ctx), NULL) <= 0 || EVP_DigestUpdate(&ctx, s->session->master_key, s->session->master_key_length) <= 0 || EVP_DigestUpdate(&ctx, ssl3_pad_2, npad) <= 0 || EVP_DigestUpdate(&ctx, md_buf, i) <= 0 || EVP_DigestFinal_ex(&ctx, p, &ret) <= 0) { SSLerr(SSL_F_SSL3_HANDSHAKE_MAC, ERR_R_INTERNAL_ERROR); ret = 0; } EVP_MD_CTX_cleanup(&ctx); return ((int)ret); }
ikptr ikrt_openssl_evp_md_ctx_md (ikptr s_ctx, ikpcb * pcb) { #ifdef HAVE_EVP_MD_CTX_MD const EVP_MD_CTX * ctx = IK_EVP_MD_CTX(s_ctx); const EVP_MD* rv; rv = EVP_MD_CTX_md(ctx); return (rv)? ika_pointer_alloc(pcb, (long)rv) : IK_FALSE; #else feature_failure(__func__); #endif }
/* * call-seq: * digest.reset -> self * * Resets the Digest in the sense that any Digest#update that has been * performed is abandoned and the Digest is set to its initial state again. * */ static VALUE ossl_digest_reset(VALUE self) { EVP_MD_CTX *ctx; GetDigest(self, ctx); if (EVP_DigestInit_ex(ctx, EVP_MD_CTX_md(ctx), NULL) != 1) { ossl_raise(eDigestError, "Digest initialization failed."); } return self; }
static LUA_FUNCTION(openssl_digest_ctx_reset) { EVP_MD_CTX *ctx = CHECK_OBJECT(1, EVP_MD_CTX, "openssl.evp_digest_ctx"); const EVP_MD *md = EVP_MD_CTX_md(ctx); ENGINE* e = ctx->engine; int ret = EVP_MD_CTX_cleanup(ctx); if (ret) { EVP_MD_CTX_init(ctx); EVP_DigestInit_ex(ctx, md, e); } return openssl_pushresult(L, ret); }
static int digest_reset(lua_State *L) { EVP_MD_CTX *c = (EVP_MD_CTX*)luaL_checkudata(L, 1, LUACRYPTO_DIGESTNAME); const EVP_MD *t = EVP_MD_CTX_md(c); if (!EVP_MD_CTX_cleanup(c)) { return crypto_error(L); } EVP_MD_CTX_init(c); if (!EVP_DigestInit_ex(c, t, NULL)) { return crypto_error(L); } return 0; }
static void digest_finish(PX_MD * h, uint8 *dst) { EVP_MD_CTX *ctx = (EVP_MD_CTX *) h->p.ptr; const EVP_MD *md = EVP_MD_CTX_md(ctx); EVP_DigestFinal(ctx, dst, NULL); /* * Some builds of 0.9.7x clear all of ctx in EVP_DigestFinal. Fix it by * reinitializing ctx. */ EVP_DigestInit(ctx, md); }
/** Returns the OpenSSL keyblock size * * @copyright (c) 2002-2016, Jouni Malinen <*****@*****.**> and contributors * All Rights Reserved. * * These programs are licensed under the BSD license (the one with * advertisement clause removed). * * this function shamelessly stolen from from * hostap:src/crypto/tls_openssl.c:openssl_get_keyblock_size() * * @param[in] request The current request. * @param[in] ssl The current SSL session. * @return * - -1 problem with the session. * - >=0 length of the block. */ int tls_utils_keyblock_size_get(REQUEST *request, SSL *ssl) { const EVP_CIPHER *c; const EVP_MD *h; #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) int md_size; if (ssl->enc_read_ctx == NULL || ssl->enc_read_ctx->cipher == NULL || ssl->read_hash == NULL) return -1; c = ssl->enc_read_ctx->cipher; h = EVP_MD_CTX_md(ssl->read_hash); if (h) md_size = EVP_MD_size(h); else if (ssl->s3) md_size = ssl->s3->tmp.new_mac_secret_size; else return -1; RDEBUG2("OpenSSL: keyblock size: key_len=%d MD_size=%d " "IV_len=%d", EVP_CIPHER_key_length(c), md_size, EVP_CIPHER_iv_length(c)); return 2 * (EVP_CIPHER_key_length(c) + md_size + EVP_CIPHER_iv_length(c)); #else const SSL_CIPHER *ssl_cipher; int cipher, digest; ssl_cipher = SSL_get_current_cipher(ssl); if (!ssl_cipher) return -1; cipher = SSL_CIPHER_get_cipher_nid(ssl_cipher); digest = SSL_CIPHER_get_digest_nid(ssl_cipher); RDEBUG2("OpenSSL: cipher nid %d digest nid %d", cipher, digest); if (cipher < 0 || digest < 0) return -1; c = EVP_get_cipherbynid(cipher); h = EVP_get_digestbynid(digest); if (!c || !h) return -1; RDEBUG2("OpenSSL: keyblock size: key_len=%d MD_size=%d IV_len=%d", EVP_CIPHER_key_length(c), EVP_MD_size(h), EVP_CIPHER_iv_length(c)); return 2 * (EVP_CIPHER_key_length(c) + EVP_MD_size(h) + EVP_CIPHER_iv_length(c)); #endif }
static int evp_reset(lua_State *L) { HANDLER_EVP *c = evp_pget(L, 1); #if CRYPTO_OPENSSL const EVP_MD *t = EVP_MD_CTX_md(c); EVP_MD_CTX_cleanup(c); EVP_MD_CTX_init(c); EVP_DigestInit_ex(c, t, NULL); #elif CRYPTO_GCRYPT gcry_md_reset(*c); #endif return 0; }
int ssl3_update_handshake_hash(SSL *ssl, const uint8_t *in, size_t in_len) { /* Depending on the state of the handshake, either the handshake buffer may be * active, the rolling hash, or both. */ if (ssl->s3->handshake_buffer != NULL) { size_t new_len = ssl->s3->handshake_buffer->length + in_len; if (new_len < in_len) { OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); return 0; } if (!BUF_MEM_grow(ssl->s3->handshake_buffer, new_len)) { return 0; } memcpy(ssl->s3->handshake_buffer->data + new_len - in_len, in, in_len); } if (EVP_MD_CTX_md(&ssl->s3->handshake_hash) != NULL) { EVP_DigestUpdate(&ssl->s3->handshake_hash, in, in_len); } if (EVP_MD_CTX_md(&ssl->s3->handshake_md5) != NULL) { EVP_DigestUpdate(&ssl->s3->handshake_md5, in, in_len); } return 1; }
/* tls1_handshake_digest calculates the current handshake hash and writes it to * |out|, which has space for |out_len| bytes. It returns the number of bytes * written or -1 in the event of an error. This function works on a copy of the * underlying digests so can be called multiple times and prior to the final * update etc. */ int tls1_handshake_digest(SSL *s, uint8_t *out, size_t out_len) { size_t md5_len = 0; if (EVP_MD_CTX_md(&s->s3->handshake_md5) != NULL && !append_digest(&s->s3->handshake_md5, out, &md5_len, out_len)) { return -1; } size_t len; if (!append_digest(&s->s3->handshake_hash, out + md5_len, &len, out_len - md5_len)) { return -1; } return (int)(md5_len + len); }
static int sig_in(BIO *b) { BIO_OK_CTX *ctx; EVP_MD_CTX *md; unsigned char tmp[EVP_MAX_MD_SIZE]; int ret = 0; const EVP_MD *digest; int md_size; void *md_data; ctx = BIO_get_data(b); md = ctx->md; digest = EVP_MD_CTX_md(md); md_size = EVP_MD_size(digest); md_data = EVP_MD_CTX_md_data(md); if ((int)(ctx->buf_len - ctx->buf_off) < 2 * md_size) return 1; if (!EVP_DigestInit_ex(md, digest, NULL)) goto berr; memcpy(md_data, &(ctx->buf[ctx->buf_off]), md_size); longswap(md_data, md_size); ctx->buf_off += md_size; if (!EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN))) goto berr; if (!EVP_DigestFinal_ex(md, tmp, NULL)) goto berr; ret = memcmp(&(ctx->buf[ctx->buf_off]), tmp, md_size) == 0; ctx->buf_off += md_size; if (ret == 1) { ctx->sigio = 0; if (ctx->buf_len != ctx->buf_off) { memmove(ctx->buf, &(ctx->buf[ctx->buf_off]), ctx->buf_len - ctx->buf_off); } ctx->buf_len -= ctx->buf_off; ctx->buf_off = 0; } else { ctx->cont = 0; } return 1; berr: BIO_clear_retry_flags(b); return 0; }
/** @impl_interface_method{RTCRDIGESTDESC::pfnInit} */ static DECLCALLBACK(int) rtCrDigestOsslEvp_Init(void *pvState, void *pvOpaque, bool fReInit) { EVP_MD_CTX *pThis = (EVP_MD_CTX *)pvState; EVP_MD const *pEvpType = (EVP_MD const *)pvOpaque; if (fReInit) { pEvpType = EVP_MD_CTX_md(pThis); EVP_MD_CTX_cleanup(pThis); } AssertPtrReturn(pEvpType, VERR_INVALID_PARAMETER); Assert(pEvpType->md_size); if (EVP_DigestInit(pThis, pEvpType)) return VINF_SUCCESS; return VERR_CR_DIGEST_OSSL_DIGEST_INIT_ERROR; }
int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int *siglen, EVP_PKEY *pkey) { unsigned char m[EVP_MAX_MD_SIZE]; unsigned int m_len = 0; int i = 0; size_t sltmp; EVP_PKEY_CTX *pkctx = NULL; *siglen = 0; if (EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_FINALISE)) { if (!EVP_DigestFinal_ex(ctx, m, &m_len)) goto err; } else { int rv = 0; EVP_MD_CTX *tmp_ctx = EVP_MD_CTX_new(); if (tmp_ctx == NULL) { EVPerr(EVP_F_EVP_SIGNFINAL, ERR_R_MALLOC_FAILURE); return 0; } rv = EVP_MD_CTX_copy_ex(tmp_ctx, ctx); if (rv) rv = EVP_DigestFinal_ex(tmp_ctx, m, &m_len); EVP_MD_CTX_free(tmp_ctx); if (!rv) return 0; } sltmp = (size_t)EVP_PKEY_size(pkey); i = 0; pkctx = EVP_PKEY_CTX_new(pkey, NULL); if (pkctx == NULL) goto err; if (EVP_PKEY_sign_init(pkctx) <= 0) goto err; if (EVP_PKEY_CTX_set_signature_md(pkctx, EVP_MD_CTX_md(ctx)) <= 0) goto err; if (EVP_PKEY_sign(pkctx, sigret, &sltmp, m, m_len) <= 0) goto err; *siglen = sltmp; i = 1; err: EVP_PKEY_CTX_free(pkctx); return i; }
int x509_digest_sign_algorithm(EVP_MD_CTX *ctx, X509_ALGOR *algor) { EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx); if (pkey == NULL) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_CONTEXT_NOT_INITIALISED); return 0; } if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA) { int pad_mode; if (!EVP_PKEY_CTX_get_rsa_padding(ctx->pctx, &pad_mode)) { return 0; } /* RSA-PSS has special signature algorithm logic. */ if (pad_mode == RSA_PKCS1_PSS_PADDING) { return x509_rsa_ctx_to_pss(ctx, algor); } } if (EVP_PKEY_id(pkey) == EVP_PKEY_ED25519) { return X509_ALGOR_set0(algor, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL); } /* Default behavior: look up the OID for the algorithm/hash pair and encode * that. */ const EVP_MD *digest = EVP_MD_CTX_md(ctx); if (digest == NULL) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_CONTEXT_NOT_INITIALISED); return 0; } int sign_nid; if (!OBJ_find_sigid_by_algs(&sign_nid, EVP_MD_type(digest), EVP_PKEY_id(pkey))) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED); return 0; } /* RSA signature algorithms include an explicit NULL parameter. Others omit * it. */ int paramtype = (EVP_PKEY_id(pkey) == EVP_PKEY_RSA) ? V_ASN1_NULL : V_ASN1_UNDEF; X509_ALGOR_set0(algor, OBJ_nid2obj(sign_nid), paramtype, NULL); return 1; }
static int block_in(BIO *b) { BIO_OK_CTX *ctx; EVP_MD_CTX *md; unsigned long tl = 0; unsigned char tmp[EVP_MAX_MD_SIZE]; int md_size; ctx = BIO_get_data(b); md = ctx->md; md_size = EVP_MD_size(EVP_MD_CTX_md(md)); assert(sizeof(tl) >= OK_BLOCK_BLOCK); /* always true */ tl = ctx->buf[0]; tl <<= 8; tl |= ctx->buf[1]; tl <<= 8; tl |= ctx->buf[2]; tl <<= 8; tl |= ctx->buf[3]; if (ctx->buf_len < tl + OK_BLOCK_BLOCK + md_size) return 1; if (!EVP_DigestUpdate(md, (unsigned char *)&(ctx->buf[OK_BLOCK_BLOCK]), tl)) goto berr; if (!EVP_DigestFinal_ex(md, tmp, NULL)) goto berr; if (memcmp(&(ctx->buf[tl + OK_BLOCK_BLOCK]), tmp, md_size) == 0) { /* there might be parts from next block lurking around ! */ ctx->buf_off_save = tl + OK_BLOCK_BLOCK + md_size; ctx->buf_len_save = ctx->buf_len; ctx->buf_off = OK_BLOCK_BLOCK; ctx->buf_len = tl + OK_BLOCK_BLOCK; ctx->blockout = 1; } else { ctx->cont = 0; } return 1; berr: BIO_clear_retry_flags(b); return 0; }
static int sig_out(BIO *b) { BIO_OK_CTX *ctx; EVP_MD_CTX *md; const EVP_MD *digest; int md_size; void *md_data; ctx = BIO_get_data(b); md = ctx->md; digest = EVP_MD_CTX_md(md); md_size = EVP_MD_size(digest); md_data = EVP_MD_CTX_md_data(md); if (ctx->buf_len + 2 * md_size > OK_BLOCK_SIZE) return 1; if (!EVP_DigestInit_ex(md, digest, NULL)) goto berr; /* * FIXME: there's absolutely no guarantee this makes any sense at all, * particularly now EVP_MD_CTX has been restructured. */ if (RAND_bytes(md_data, md_size) <= 0) goto berr; memcpy(&(ctx->buf[ctx->buf_len]), md_data, md_size); longswap(&(ctx->buf[ctx->buf_len]), md_size); ctx->buf_len += md_size; if (!EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN))) goto berr; if (!EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL)) goto berr; ctx->buf_len += md_size; ctx->blockout = 1; ctx->sigio = 0; return 1; berr: BIO_clear_retry_flags(b); return 0; }
/* * Public */ const EVP_MD * GetDigestPtr(VALUE obj) { const EVP_MD *md; if (TYPE(obj) == T_STRING) { const char *name = StringValueCStr(obj); md = EVP_get_digestbyname(name); if (!md) ossl_raise(rb_eRuntimeError, "Unsupported digest algorithm (%s).", name); } else { EVP_MD_CTX *ctx; SafeGetDigest(obj, ctx); md = EVP_MD_CTX_md(ctx); } return md; }