int ndn_merkle_root_hash(const unsigned char *msg, size_t size, const struct ndn_parsed_ContentObject *co, const EVP_MD *digest_type, MP_info *merkle_path_info, unsigned char *result, int result_size) { int node = ASN1_INTEGER_get(merkle_path_info->node); EVP_MD_CTX digest_context; EVP_MD_CTX *digest_contextp = &digest_context; size_t data_size; unsigned char *input_hash[2] = {NULL, NULL}; //int hash_count = sk_ASN1_OCTET_STRING_num(merkle_path_info->hashes); int hash_index = sk_ASN1_OCTET_STRING_num(merkle_path_info->hashes) - 1; //ASN1_OCTET_STRING *sibling_hash; int res; if (result_size != EVP_MD_size(digest_type)) return -1; /* * This is the calculation for the node we're starting from * * The digest type for the leaf node we'll take from the MHT OID * We can assume that, since we're using the same digest function, the * result size will always be the same. */ EVP_MD_CTX_init(digest_contextp); EVP_DigestInit_ex(digest_contextp, digest_type, NULL); data_size = co->offset[NDN_PCO_E_Content] - co->offset[NDN_PCO_B_Name]; res = EVP_DigestUpdate(digest_contextp, msg + co->offset[NDN_PCO_B_Name], data_size); res &= EVP_DigestFinal_ex(digest_contextp, result, NULL); EVP_MD_CTX_cleanup(digest_contextp); if (res != 1) return(-1); /* input_hash[0, 1] = address of hash for (left,right) node of parent */ while (node != 1) { input_hash[node & 1] = result; input_hash[(node & 1) ^ 1] = sk_ASN1_OCTET_STRING_value(merkle_path_info->hashes, hash_index)->data; if (sk_ASN1_OCTET_STRING_value(merkle_path_info->hashes, hash_index)->length != result_size) return (-1); hash_index -= 1; #ifdef DEBUG fprintf(stderr, "node[%d].lefthash = ", parent_of(node)); for (int x = 0; x < result_size; x++) { fprintf(stderr, "%02x", input_hash[0][x]); } fprintf(stderr, "\n"); fprintf(stderr, "node[%d].righthash = ", parent_of(node)); for (int x = 0; x < result_size; x++) { fprintf(stderr, "%02x", input_hash[1][x]); } fprintf(stderr, "\n"); #endif EVP_MD_CTX_init(digest_contextp); res = EVP_DigestInit_ex(digest_contextp, digest_type, NULL); res &= EVP_DigestUpdate(digest_contextp, input_hash[0], result_size); res &= EVP_DigestUpdate(digest_contextp, input_hash[1], result_size); res &= EVP_DigestFinal_ex(digest_contextp, result, NULL); EVP_MD_CTX_cleanup(digest_contextp); if (res != 1) return(-1); node = parent_of(node); #ifdef DEBUG fprintf(stderr, "yielding node[%d] hash = ", node); for (int x = 0; x < result_size; x++) { fprintf(stderr, "%02x", result[x]); } fprintf(stderr, "\n"); #endif } return (0); }
static void digest(struct executable *x) { EVP_MD_CTX *mdctx; const EVP_MD *md; size_t sum_of_bytes_hashed; int i, ok; /* * Windows Authenticode Portable Executable Signature Format * spec version 1.0 specifies MD5 and SHA1. However, pesign * and sbsign both use SHA256, so do the same. */ md = EVP_get_digestbyname(DIGEST); if (md == NULL) { ERR_print_errors_fp(stderr); errx(1, "EVP_get_digestbyname(\"%s\") failed", DIGEST); } mdctx = EVP_MD_CTX_create(); if (mdctx == NULL) { ERR_print_errors_fp(stderr); errx(1, "EVP_MD_CTX_create(3) failed"); } ok = EVP_DigestInit_ex(mdctx, md, NULL); if (ok == 0) { ERR_print_errors_fp(stderr); errx(1, "EVP_DigestInit_ex(3) failed"); } /* * According to the Authenticode spec, we need to compute * the digest in a rather... specific manner; see "Calculating * the PE Image Hash" part of the spec for details. * * First, everything from 0 to before the PE checksum. */ digest_range(x, mdctx, 0, x->x_checksum_off); /* * Second, from after the PE checksum to before the Certificate * entry in Data Directory. */ digest_range(x, mdctx, x->x_checksum_off + x->x_checksum_len, x->x_certificate_entry_off - (x->x_checksum_off + x->x_checksum_len)); /* * Then, from after the Certificate entry to the end of headers. */ digest_range(x, mdctx, x->x_certificate_entry_off + x->x_certificate_entry_len, x->x_headers_len - (x->x_certificate_entry_off + x->x_certificate_entry_len)); /* * Then, each section in turn, as specified in the PE Section Table. * * XXX: Sorting. */ sum_of_bytes_hashed = x->x_headers_len; for (i = 0; i < x->x_nsections; i++) { digest_range(x, mdctx, x->x_section_off[i], x->x_section_len[i]); sum_of_bytes_hashed += x->x_section_len[i]; } /* * I believe this can happen with overlapping sections. */ if (sum_of_bytes_hashed > x->x_len) errx(1, "number of bytes hashed is larger than file size"); /* * I can't really explain this one; just do what the spec says. */ if (sum_of_bytes_hashed < x->x_len) { digest_range(x, mdctx, sum_of_bytes_hashed, x->x_len - (signature_size(x) + sum_of_bytes_hashed)); } ok = EVP_DigestFinal_ex(mdctx, x->x_digest, &x->x_digest_len); if (ok == 0) { ERR_print_errors_fp(stderr); errx(1, "EVP_DigestFinal_ex(3) failed"); } EVP_MD_CTX_destroy(mdctx); }
int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM, const unsigned char *mHash, const EVP_MD *Hash, const EVP_MD *mgf1Hash, int sLen) { int i; int ret = 0; int hLen, maskedDBLen, MSBits, emLen; unsigned char *H, *salt = NULL, *p; EVP_MD_CTX ctx; if (mgf1Hash == NULL) mgf1Hash = Hash; hLen = M_EVP_MD_size(Hash); if (hLen < 0) goto err; /* * Negative sLen has special meanings: * -1 sLen == hLen * -2 salt length is maximized * -N reserved */ if (sLen == -1) sLen = hLen; else if (sLen == -2) sLen = -2; else if (sLen < -2) { RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED); goto err; } MSBits = (BN_num_bits(rsa->n) - 1) & 0x7; emLen = RSA_size(rsa); if (MSBits == 0) { *EM++ = 0; emLen--; } if (sLen == -2) { sLen = emLen - hLen - 2; } else if (emLen < (hLen + sLen + 2)) { RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1,RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); goto err; } if (sLen > 0) { salt = OPENSSL_malloc(sLen); if (!salt) { RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1,ERR_R_MALLOC_FAILURE); goto err; } if (RAND_bytes(salt, sLen) <= 0) goto err; } maskedDBLen = emLen - hLen - 1; H = EM + maskedDBLen; EVP_MD_CTX_init(&ctx); if (!EVP_DigestInit_ex(&ctx, Hash, NULL) || !EVP_DigestUpdate(&ctx, zeroes, sizeof zeroes) || !EVP_DigestUpdate(&ctx, mHash, hLen)) goto err; if (sLen && !EVP_DigestUpdate(&ctx, salt, sLen)) goto err; if (!EVP_DigestFinal_ex(&ctx, H, NULL)) goto err; EVP_MD_CTX_cleanup(&ctx); /* Generate dbMask in place then perform XOR on it */ if (PKCS1_MGF1(EM, maskedDBLen, H, hLen, mgf1Hash)) goto err; p = EM; /* Initial PS XORs with all zeroes which is a NOP so just update * pointer. Note from a test above this value is guaranteed to * be non-negative. */ p += emLen - sLen - hLen - 2; *p++ ^= 0x1; if (sLen > 0) { for (i = 0; i < sLen; i++) *p++ ^= salt[i]; } if (MSBits) EM[0] &= 0xFF >> (8 - MSBits); /* H is already in place so just set final 0xbc */ EM[emLen - 1] = 0xbc; ret = 1; err: if (salt) OPENSSL_free(salt); return ret; }
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; 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 (;;) { EVP_DigestInit_ex(&c,md, NULL); if (addmd++) EVP_DigestUpdate(&c,&(md_buf[0]),mds); EVP_DigestUpdate(&c,data,datal); if (salt != NULL) EVP_DigestUpdate(&c,salt,PKCS5_SALT_LEN); EVP_DigestFinal_ex(&c,&(md_buf[0]),&mds); for (i=1; i<(unsigned int)count; i++) { EVP_DigestInit_ex(&c,md, NULL); EVP_DigestUpdate(&c,&(md_buf[0]),mds); EVP_DigestFinal_ex(&c,&(md_buf[0]),&mds); } 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; } EVP_MD_CTX_cleanup(&c); OPENSSL_cleanse(&(md_buf[0]),EVP_MAX_MD_SIZE); return(type->key_len); }
int ssl3_change_cipher_state(SSL *s, int which) { unsigned char *p,*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; /* m == NULL will lead to a crash later */ OPENSSL_assert(m); #ifndef OPENSSL_NO_COMP if (s->s3->tmp.new_compression == NULL) comp=NULL; else comp=s->s3->tmp.new_compression->method; #endif 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; ssl_replace_hash(&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; ssl_replace_hash(&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); if (i < 0) goto err2; 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); }
int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen, ASN1_TYPE *param, const EVP_CIPHER *cipher, const EVP_MD *md, int en_de) { EVP_MD_CTX ctx; unsigned char md_tmp[EVP_MAX_MD_SIZE]; unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH]; int i; PBEPARAM *pbe; int saltlen, iter; unsigned char *salt; const unsigned char *pbuf; int mdsize; int rv = 0; EVP_MD_CTX_init(&ctx); /* Extract useful info from parameter */ if (param == NULL || param->type != V_ASN1_SEQUENCE || param->value.sequence == NULL) { EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN, EVP_R_DECODE_ERROR); return 0; } pbuf = param->value.sequence->data; if (!(pbe = d2i_PBEPARAM(NULL, &pbuf, param->value.sequence->length))) { EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN, EVP_R_DECODE_ERROR); return 0; } if (!pbe->iter) iter = 1; else iter = ASN1_INTEGER_get(pbe->iter); salt = pbe->salt->data; saltlen = pbe->salt->length; if (!pass) passlen = 0; else if (passlen == -1) passlen = strlen(pass); if (!EVP_DigestInit_ex(&ctx, md, NULL)) goto err; if (!EVP_DigestUpdate(&ctx, pass, passlen)) goto err; if (!EVP_DigestUpdate(&ctx, salt, saltlen)) goto err; PBEPARAM_free(pbe); if (!EVP_DigestFinal_ex(&ctx, md_tmp, NULL)) goto err; mdsize = EVP_MD_size(md); if (mdsize < 0) return 0; for (i = 1; i < iter; i++) { if (!EVP_DigestInit_ex(&ctx, md, NULL)) goto err; if (!EVP_DigestUpdate(&ctx, md_tmp, mdsize)) goto err; if (!EVP_DigestFinal_ex(&ctx, md_tmp, NULL)) goto err; } OPENSSL_assert(EVP_CIPHER_key_length(cipher) <= (int)sizeof(md_tmp)); memcpy(key, md_tmp, EVP_CIPHER_key_length(cipher)); OPENSSL_assert(EVP_CIPHER_iv_length(cipher) <= 16); memcpy(iv, md_tmp + (16 - EVP_CIPHER_iv_length(cipher)), EVP_CIPHER_iv_length(cipher)); if (!EVP_CipherInit_ex(cctx, cipher, NULL, key, iv, en_de)) goto err; OPENSSL_cleanse(md_tmp, EVP_MAX_MD_SIZE); OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH); OPENSSL_cleanse(iv, EVP_MAX_IV_LENGTH); rv = 1; err: EVP_MD_CTX_cleanup(&ctx); return rv; }
static int ssl3_handshake_mac(SSL *s, int md_nid, const char *sender, int len, uint8_t *p) { unsigned int ret; int npad, n; unsigned int i; uint8_t md_buf[EVP_MAX_MD_SIZE]; EVP_MD_CTX ctx, *d = NULL; if (s->s3->handshake_buffer && !ssl3_digest_cached_records(s, free_handshake_buffer)) { 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) { OPENSSL_PUT_ERROR(SSL, ssl3_handshake_mac, SSL_R_NO_REQUIRED_DIGEST); return 0; } EVP_MD_CTX_init(&ctx); if (!EVP_MD_CTX_copy_ex(&ctx, d)) { EVP_MD_CTX_cleanup(&ctx); OPENSSL_PUT_ERROR(SSL, ssl3_handshake_mac, ERR_LIB_EVP); return 0; } n = EVP_MD_CTX_size(&ctx); if (n < 0) { return 0; } 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); if (!EVP_DigestInit_ex(&ctx, EVP_MD_CTX_md(&ctx), NULL)) { EVP_MD_CTX_cleanup(&ctx); OPENSSL_PUT_ERROR(SSL, ssl3_handshake_mac, ERR_LIB_EVP); return 0; } 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 ret; }
static int ssl3_handshake_mac(SSL *ssl, int md_nid, const char *sender, size_t sender_len, uint8_t *p) { unsigned int ret; size_t npad, n; unsigned int i; uint8_t md_buf[EVP_MAX_MD_SIZE]; EVP_MD_CTX ctx; const EVP_MD_CTX *ctx_template; if (md_nid == NID_md5) { ctx_template = &ssl->s3->handshake_md5; } else if (md_nid == EVP_MD_CTX_type(&ssl->s3->handshake_hash)) { ctx_template = &ssl->s3->handshake_hash; } else { OPENSSL_PUT_ERROR(SSL, SSL_R_NO_REQUIRED_DIGEST); return 0; } EVP_MD_CTX_init(&ctx); if (!EVP_MD_CTX_copy_ex(&ctx, ctx_template)) { EVP_MD_CTX_cleanup(&ctx); OPENSSL_PUT_ERROR(SSL, ERR_LIB_EVP); return 0; } static const uint8_t kPad1[48] = { 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, }; static const uint8_t kPad2[48] = { 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, }; n = EVP_MD_CTX_size(&ctx); npad = (48 / n) * n; if (sender != NULL) { EVP_DigestUpdate(&ctx, sender, sender_len); } EVP_DigestUpdate(&ctx, ssl->session->master_key, ssl->session->master_key_length); EVP_DigestUpdate(&ctx, kPad1, npad); EVP_DigestFinal_ex(&ctx, md_buf, &i); if (!EVP_DigestInit_ex(&ctx, EVP_MD_CTX_md(&ctx), NULL)) { EVP_MD_CTX_cleanup(&ctx); OPENSSL_PUT_ERROR(SSL, ERR_LIB_EVP); return 0; } EVP_DigestUpdate(&ctx, ssl->session->master_key, ssl->session->master_key_length); EVP_DigestUpdate(&ctx, kPad2, npad); EVP_DigestUpdate(&ctx, md_buf, i); EVP_DigestFinal_ex(&ctx, p, &ret); EVP_MD_CTX_cleanup(&ctx); return ret; }
int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md, ENGINE *impl) { int rv = 0; int i, j, reset = 0; unsigned char pad[HMAC_MAX_MD_CBLOCK_SIZE]; /* 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); if (!ossl_assert(j <= (int)sizeof(ctx->key))) return 0; if (j < len) { if (!EVP_DigestInit_ex(ctx->md_ctx, md, impl) || !EVP_DigestUpdate(ctx->md_ctx, key, len) || !EVP_DigestFinal_ex(ctx->md_ctx, ctx->key, &ctx->key_length)) return 0; } 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_SIZE) memset(&ctx->key[ctx->key_length], 0, HMAC_MAX_MD_CBLOCK_SIZE - ctx->key_length); } if (reset) { for (i = 0; i < HMAC_MAX_MD_CBLOCK_SIZE; i++) pad[i] = 0x36 ^ ctx->key[i]; if (!EVP_DigestInit_ex(ctx->i_ctx, md, impl) || !EVP_DigestUpdate(ctx->i_ctx, pad, EVP_MD_block_size(md))) goto err; for (i = 0; i < HMAC_MAX_MD_CBLOCK_SIZE; i++) pad[i] = 0x5c ^ ctx->key[i]; if (!EVP_DigestInit_ex(ctx->o_ctx, md, impl) || !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; rv = 1; err: if (reset) OPENSSL_cleanse(pad, sizeof(pad)); return rv; }
main(int argc, char *argv[]) { EVP_MD_CTX *mdctx; EVP_MD_CTX *mdctxdup; const EVP_MD *md; const EVP_MD *mddup; char *mess1; unsigned char md_value[EVP_MAX_MD_SIZE]; unsigned char md_valuedup[EVP_MAX_MD_SIZE]; int md_len,md_lendup, i; char originalBinary[24]; char randomBinary[24]; OpenSSL_add_all_digests(); if(!argv[1]) { printf("Usage: mdtest digestname\n"); exit(1); } md = EVP_get_digestbyname(argv[1]) ; if(!md) { printf("Unknown message digest %s\n", argv[1]); exit(1); } int dontExit =1; char *str ; int num1,num2,timesExecuted=0; srand(time(NULL)); while(dontExit) { timesExecuted++; mess1 = (char*)malloc(33); num1 = rand(); sprintf(mess1,"%d",num1); //mess1 = rand_string(mess1,3); mdctx = EVP_MD_CTX_create(); EVP_DigestInit_ex(mdctx, md, NULL); EVP_DigestUpdate(mdctx, mess1, strlen(mess1)); EVP_DigestFinal_ex(mdctx, md_value, &md_len); EVP_MD_CTX_destroy(mdctx); //printf("Input Original: %s\n",mess1); //printf("Digest Original: "); //for(i = 0; i < md_len; i++) //printf("%02x", md_value[i]); //printf("\n"); str = (char*)malloc(32); num2 = rand(); sprintf(str,"%d",num2); mdctxdup = EVP_MD_CTX_create(); EVP_DigestInit_ex(mdctxdup, md, NULL); EVP_DigestUpdate(mdctxdup, str, strlen(str)); EVP_DigestFinal_ex(mdctxdup, md_valuedup, &md_lendup); EVP_MD_CTX_destroy(mdctxdup); if((md_value[0] == md_valuedup[0]) && (md_value[1] == md_valuedup[1]) && (md_value[2] == md_valuedup[2]) ) { break; } free(mess1); free(str); } printf("Input Original: %s\n",mess1); printf("Digest Original: "); for(i = 0; i < md_len; i++) printf("%02x", md_value[i]); printf("\n"); printf("Input Random: %s\n",str); printf("Digest Random: "); for(i = 0; i < md_lendup; i++) printf("%02x", md_valuedup[i]); printf("\n"); printf("Times executed : %d\n",timesExecuted); /* Call this once before exit. */ EVP_cleanup(); exit(0); }
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 = EVP_CIPHER_key_length(type); niv = EVP_CIPHER_iv_length(type); OPENSSL_assert(nkey <= EVP_MAX_KEY_LENGTH); OPENSSL_assert(niv <= EVP_MAX_IV_LENGTH); if (data == NULL) return nkey; c = EVP_MD_CTX_new(); if (c == NULL) goto err; 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 = EVP_CIPHER_key_length(type); err: EVP_MD_CTX_free(c); OPENSSL_cleanse(md_buf, sizeof(md_buf)); return rv; }
extern "C" int32_t EvpDigestInitEx(EVP_MD_CTX* ctx, const EVP_MD* type, ENGINE* impl) { return EVP_DigestInit_ex(ctx, type, impl); }
/** * Esta función se encargará de producir, lo que para el SAT[1], es un sello * digital. Este sello digital consiste en el firmado digital del hash de un * string, que para los casos de un CFDi se trataría de la cadena original * * El usuario es responsable de liberar la memoria del resultado (con free()) * [1]: http://www.sat.gob.mx */ unsigned char * sello_alloc(const char *keyfile, const char *digest, const unsigned char *cadena, const int verbose) { int read = 0; int len = 0; unsigned char *buffer = NULL; const unsigned char *tmp; unsigned char signbuffer[1024]; unsigned int signlen = 0; char *data = NULL; FILE *file = NULL; BIO* err = NULL; EVP_MD_CTX mdctx; EVP_PKEY *privateKey = NULL; file = fopen(keyfile, "rb"); if ( file == NULL ) { /* An error ocurred */ if ( verbose ) { fprintf(stderr, "No fue posible leer correctamente el archivo %s.\n", keyfile); } return NULL; } len = fseek(file, 0, SEEK_END); if ( len ) { /* An error did occur */ if ( verbose ) { fprintf(stderr, "No fue posible obtener el final del archivo %s.\n", keyfile); } fclose(file); return NULL; } len = ftell(file); rewind(file); buffer = (unsigned char *)calloc(len + 1, sizeof(unsigned char)); read = fread(buffer, sizeof(unsigned char), len, file); fclose(file); if ( read != len ) { if ( verbose ) { fprintf(stderr, "An error has ocurred. The number of items read was %d, but it should be %d instead.\n", read, len); free(buffer); } return NULL; } /* Set the BIO method for the error messages */ if ( err == NULL ) { if ( (err = BIO_new(BIO_s_file())) ) { BIO_set_fp(err, stderr, BIO_NOCLOSE|BIO_FP_TEXT); } } /* Now convert the bytes to a EVP_PKEY structure */ tmp = buffer; privateKey = d2i_AutoPrivateKey(NULL, &tmp, len); if ( privateKey == NULL ) { if ( verbose ) { BIO_printf(err, "Error at reading the private key on %s.\n", keyfile); ERR_print_errors(err); } free(buffer); return NULL; } free(buffer); /* Add all digest algorithms to the table */ OpenSSL_add_all_digests(); /* Initialize the digest context */ EVP_MD_CTX_init(&mdctx); if ( EVP_DigestInit_ex(&mdctx, EVP_get_digestbyname(digest), 0 ) == 0 ) { if ( verbose ) { BIO_printf(err, "Error at initializing the digest context to use '%s' as digest algorithm.\n", digest); ERR_print_errors(err); } EVP_PKEY_free(privateKey); EVP_cleanup(); BIO_free(err); return NULL; } /* Sign up the data in the current context */ if ( EVP_SignInit_ex(&mdctx, EVP_get_digestbyname(digest), 0) == 0 ) { if ( verbose ) { BIO_printf(err, "Error at setting up the signing context to use digest '%s'.\n", digest); ERR_print_errors(err); } EVP_PKEY_free(privateKey); EVP_cleanup(); BIO_free(err); return NULL; } if ( EVP_SignUpdate(&mdctx, cadena, strlen((char *)cadena)) == 0 ) { if ( verbose ) { BIO_printf(err, "Error hashing the data into the signing context.\n"); ERR_print_errors(err); } EVP_PKEY_free(privateKey); EVP_cleanup(); BIO_free(err); return NULL; } signlen = sizeof(signbuffer); memset(signbuffer, 0, 1024); if ( EVP_SignFinal(&mdctx, signbuffer, (unsigned int* )&signlen, privateKey) == 0 ) { if ( verbose ) { BIO_printf(err, "Error signing the data in the context with the private key.\n"); ERR_print_errors(err); } EVP_PKEY_free(privateKey); EVP_cleanup(); BIO_free(err); return NULL; } EVP_MD_CTX_cleanup(&mdctx); EVP_PKEY_free(privateKey); EVP_cleanup(); BIO_free(err); /* Now prepare the data to be base64 encoded */ base64_encode_alloc((const char *)signbuffer, signlen, &data); return (unsigned char *)data; }
/*- * This function hijacks the RNG to feed it the chosen ECDSA key and nonce. * The ECDSA KATs are from: * - the X9.62 draft (4) * - NIST CAVP (720) * * It uses the low-level ECDSA_sign_setup instead of EVP to control the RNG. * NB: This is not how applications should use ECDSA; this is only for testing. * * Tests the library can successfully: * - generate public keys that matches those KATs * - create ECDSA signatures that match those KATs * - accept those signatures as valid */ static int x9_62_tests(int n) { int nid, md_nid, ret = 0; const char *r_in = NULL, *s_in = NULL, *tbs = NULL; unsigned char *pbuf = NULL, *qbuf = NULL, *message = NULL; unsigned char digest[EVP_MAX_MD_SIZE]; unsigned int dgst_len = 0; long q_len, msg_len = 0; size_t p_len; EVP_MD_CTX *mctx = NULL; EC_KEY *key = NULL; ECDSA_SIG *signature = NULL; BIGNUM *r = NULL, *s = NULL; BIGNUM *kinv = NULL, *rp = NULL; const BIGNUM *sig_r = NULL, *sig_s = NULL; nid = ecdsa_cavs_kats[n].nid; md_nid = ecdsa_cavs_kats[n].md_nid; r_in = ecdsa_cavs_kats[n].r; s_in = ecdsa_cavs_kats[n].s; tbs = ecdsa_cavs_kats[n].msg; numbers[0] = ecdsa_cavs_kats[n].d; numbers[1] = ecdsa_cavs_kats[n].k; TEST_info("ECDSA KATs for curve %s", OBJ_nid2sn(nid)); if (!TEST_ptr(mctx = EVP_MD_CTX_new()) /* get the message digest */ || !TEST_ptr(message = OPENSSL_hexstr2buf(tbs, &msg_len)) || !TEST_true(EVP_DigestInit_ex(mctx, EVP_get_digestbynid(md_nid), NULL)) || !TEST_true(EVP_DigestUpdate(mctx, message, msg_len)) || !TEST_true(EVP_DigestFinal_ex(mctx, digest, &dgst_len)) /* create the key */ || !TEST_ptr(key = EC_KEY_new_by_curve_name(nid)) /* load KAT variables */ || !TEST_ptr(r = BN_new()) || !TEST_ptr(s = BN_new()) || !TEST_true(BN_hex2bn(&r, r_in)) || !TEST_true(BN_hex2bn(&s, s_in)) /* swap the RNG source */ || !TEST_true(change_rand())) goto err; /* public key must match KAT */ use_fake = 1; if (!TEST_true(EC_KEY_generate_key(key)) || !TEST_true(p_len = EC_KEY_key2buf(key, POINT_CONVERSION_UNCOMPRESSED, &pbuf, NULL)) || !TEST_ptr(qbuf = OPENSSL_hexstr2buf(ecdsa_cavs_kats[n].Q, &q_len)) || !TEST_int_eq(q_len, p_len) || !TEST_mem_eq(qbuf, q_len, pbuf, p_len)) goto err; /* create the signature via ECDSA_sign_setup to avoid use of ECDSA nonces */ use_fake = 1; if (!TEST_true(ECDSA_sign_setup(key, NULL, &kinv, &rp)) || !TEST_ptr(signature = ECDSA_do_sign_ex(digest, dgst_len, kinv, rp, key)) /* verify the signature */ || !TEST_int_eq(ECDSA_do_verify(digest, dgst_len, signature, key), 1)) goto err; /* compare the created signature with the expected signature */ ECDSA_SIG_get0(signature, &sig_r, &sig_s); if (!TEST_BN_eq(sig_r, r) || !TEST_BN_eq(sig_s, s)) goto err; ret = 1; err: /* restore the RNG source */ if (!TEST_true(restore_rand())) ret = 0; OPENSSL_free(message); OPENSSL_free(pbuf); OPENSSL_free(qbuf); EC_KEY_free(key); ECDSA_SIG_free(signature); BN_free(r); BN_free(s); EVP_MD_CTX_free(mctx); BN_clear_free(kinv); BN_clear_free(rp); 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) { HASH_CTX md_state; void (*md_final_raw)(HASH_CTX *ctx, uint8_t *md_out); void (*md_transform)(HASH_CTX *ctx, const uint8_t *block); unsigned md_size, md_block_size = 64, md_block_shift = 6; // md_length_size is the number of bytes in the length field that terminates // the hash. unsigned md_length_size = 8; // Bound the acceptable input so we can forget about many possible overflows // later in this function. This is redundant with the record size limits in // TLS. if (data_plus_mac_plus_padding_size >= 1024 * 1024) { assert(0); return 0; } switch (EVP_MD_type(md)) { case NID_sha1: SHA1_Init(&md_state.sha1); md_final_raw = tls1_sha1_final_raw; md_transform = tls1_sha1_transform; md_size = SHA_DIGEST_LENGTH; break; case NID_sha256: SHA256_Init(&md_state.sha256); md_final_raw = tls1_sha256_final_raw; md_transform = tls1_sha256_transform; md_size = SHA256_DIGEST_LENGTH; break; case NID_sha384: SHA384_Init(&md_state.sha512); md_final_raw = tls1_sha512_final_raw; md_transform = tls1_sha512_transform; md_size = SHA384_DIGEST_LENGTH; md_block_size = 128; md_block_shift = 7; 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_block_size == (1u << md_block_shift)); assert(md_size <= EVP_MAX_MD_SIZE); static const size_t 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 |kVarianceBlocks| // blocks can vary based on the padding and on the hash used. This value // must be derived from public information. const size_t kVarianceBlocks = ( 255 + 1 + // maximum padding bytes + padding length md_size + // length of hash's output md_block_size - 1 // ceiling ) / md_block_size + 1; // the 0x80 marker and the encoded message length could or not // require an extra block; since the exact value depends on the // message length; thus, one extra block is always added to run // in constant time. // From now on we're dealing with the MAC, which conceptually has 13 // bytes of `header' before the start of the data. size_t 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. size_t max_mac_bytes = len - md_size - 1; // num_blocks is the maximum number of hash blocks. size_t 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. size_t num_starting_blocks = 0; // k is the starting byte offset into the conceptual header||data where // we start processing. size_t k = 0; // mac_end_offset is the index just past the end of the data to be MACed. size_t 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. size_t c = mac_end_offset & (md_block_size - 1); // index_a is the hash block number that contains the 0x80 terminating value. size_t index_a = mac_end_offset >> md_block_shift; // index_b is the hash block number that contains the 64-bit hash length, in // bits. size_t index_b = (mac_end_offset + md_length_size) >> md_block_shift; if (num_blocks > kVarianceBlocks) { num_starting_blocks = num_blocks - kVarianceBlocks; k = md_block_size * num_starting_blocks; } // bits is the hash-length in bits. It includes the additional hash // block for the masked HMAC key. size_t bits = 8 * mac_end_offset; // at most 18 bits to represent // Compute the initial HMAC block. bits += 8 * md_block_size; // hmac_pad is the masked HMAC key. uint8_t hmac_pad[MAX_HASH_BLOCK_SIZE]; OPENSSL_memset(hmac_pad, 0, md_block_size); assert(mac_secret_length <= sizeof(hmac_pad)); OPENSSL_memcpy(hmac_pad, mac_secret, mac_secret_length); for (size_t i = 0; i < md_block_size; i++) { hmac_pad[i] ^= 0x36; } md_transform(&md_state, hmac_pad); // The length check means |bits| fits in four bytes. uint8_t length_bytes[MAX_HASH_BIT_COUNT_BYTES]; OPENSSL_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. uint8_t first_block[MAX_HASH_BLOCK_SIZE]; OPENSSL_memcpy(first_block, header, 13); OPENSSL_memcpy(first_block + 13, data, md_block_size - 13); md_transform(&md_state, first_block); for (size_t i = 1; i < k / md_block_size; i++) { md_transform(&md_state, data + md_block_size * i - 13); } } uint8_t mac_out[EVP_MAX_MD_SIZE]; OPENSSL_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 (size_t 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 (size_t j = 0; j < md_block_size; j++) { uint8_t b = 0; if (k < kHeaderLength) { b = header[k]; } else if (k < data_plus_mac_plus_padding_size + kHeaderLength) { b = data[k - kHeaderLength]; } k++; uint8_t is_past_c = is_block_a & constant_time_ge_8(j, c); uint8_t 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, block); md_final_raw(&md_state, block); // If this is index_b, copy the hash value to |mac_out|. for (size_t j = 0; j < md_size; j++) { mac_out[j] |= block[j] & is_block_b; } } EVP_MD_CTX md_ctx; 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 (size_t 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); unsigned md_out_size_u; 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; }
/** * @brief Sign a TFTF * * @param filename The pathname to the TFTF file to sign. * @param signature_format The pathname to the TFTF file to sign. * @param signature_algorithm The pathname to the TFTF file to sign. * @param key_filename The pathname to the TFTF file to sign. * @param write_if_good If true and we were able to sign it, write the signed * TFTF file. If false only verify we can sign the TFTF. * @param verbose If true, display the signed TFTF. * * @returns True on success, false on failure */ bool sign_tftf(const char * filename, const uint32_t signature_algorithm, const char * key_name, const char * key_filename, const bool write_if_good, const bool verbose) { bool success = false; int status; ssize_t tftf_size; tftf_header * tftf_hdr = NULL; char * loc_key_filename = NULL; /* Sanity check */ if (!filename || !key_filename) { fprintf (stderr, "ERROR (sign_tftf): invalid parameters\n"); return false; } /* Create a local copy of the key_filename */ loc_key_filename = malloc(strlen(key_filename) + 1); if (!loc_key_filename) { fprintf(stderr, "ERROR (sign_tftf): can't alloc. local key_filename\n"); return false; } strcpy(loc_key_filename, key_filename); /* Read in the TFTF file as a blob */ tftf_hdr = (tftf_header *)alloc_load_file(filename, &tftf_size); if (tftf_hdr) { EVP_MD_CTX * mdctx; uint8_t * hdr_signable_start = NULL; size_t hdr_signable_length = 0; uint8_t * scn_signable_start = NULL; size_t scn_signable_length = 0; tftf_signature signature_block; uint8_t md_value[EVP_MAX_MD_SIZE]; unsigned int md_len; unsigned int sig_len = sizeof(signature_block.signature); /* Initialize the signature block */ signature_block.length = sizeof(signature_block); signature_block.type = signature_algorithm; safer_strcpy(signature_block.key_name, sizeof(signature_block.key_name), key_name); /* Extract the signable blob from the TFTF and sign it */ success = tftf_get_signable_region(tftf_hdr, &hdr_signable_start, &hdr_signable_length, &scn_signable_start, &scn_signable_length); mdctx = EVP_MD_CTX_create(); if (mdctx) { status = EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL); if (status < 1) { fprintf(stderr, "ERROR: EVP_DigestInit_ex failed: %s\n", ERR_error_string(ERR_get_error(), NULL)); goto signing_err; } status = EVP_DigestUpdate(mdctx, hdr_signable_start, hdr_signable_length); if (status < 1) { fprintf(stderr, "ERROR: EVP_DigestUpdate (hdr) failed: %s\n", ERR_error_string(ERR_get_error(), NULL)); goto signing_err; } status = EVP_DigestUpdate(mdctx, scn_signable_start, scn_signable_length); if (status < 1) { fprintf(stderr, "ERROR: EVP_DigestUpdate (scn) failed: %s\n", ERR_error_string(ERR_get_error(), NULL)); goto signing_err; } status = EVP_DigestFinal_ex(mdctx, md_value, &md_len); if (status < 1) { fprintf(stderr, "ERROR: EVP_DigestFinal_ex failed: %s\n", ERR_error_string(ERR_get_error(), NULL)); goto signing_err; } status = RSA_sign(NID_sha256, md_value, md_len, signature_block.signature, &sig_len, rsa); if (status < 1) { fprintf(stderr, "ERROR: RSA_sign failed: %s\n", ERR_error_string(ERR_get_error(), NULL)); } success = true; signing_err: EVP_MD_CTX_destroy(mdctx); } else { fprintf(stderr, "ERROR: EVP_MD_CTX_create failed\n"); } /* Append the signature block to the TFTF */ if (success) { success = tftf_add_section(&tftf_hdr, TFTF_SECTION_SIGNATURE, 0, 0, DATA_ADDRESS_TO_BE_IGNORED, (uint8_t*)&signature_block, sizeof(signature_block)); if (!success) { fprintf(stderr, "ERROR: File is signable but no room for signature\n"); } } if (success) { /* Rewrite the file with the amended TFTF */ if (write_if_good) { success = write_tftf_file(tftf_hdr, filename); } /* Show the user what they've produced? */ if (verbose) { print_tftf_file(tftf_hdr, filename); } } } /* Dispose of any local allocations */ if (tftf_hdr) { free(tftf_hdr); } if (loc_key_filename) { free(loc_key_filename); } return success; }
char execProtect() { static int callable = 0; if (!callable) { FILE * fp = fopen("auth.dat", "r"); if (fp == NULL) { fprintf(stderr, "Failed to open autherisation file\n"); lock_fail(); return 0; } size_t s = 0; char b[BUFSIZ]; int len; if ((len = fread(b, sizeof(char), BUFSIZ, fp)) <= 0) { fprintf(stderr, "Failed to read encrypted file\n"); lock_fail(); return 0; } FILE *pfp = fmemopen(pubkey, strlen(pubkey), "r"); if (pfp == NULL) { fprintf(stderr, "Failed to read internal memory\n"); lock_fail(); return 0; } RSA *pub_key = NULL; PEM_read_RSA_PUBKEY(pfp,&pub_key, NULL, NULL); if(pub_key == NULL) { fprintf(stderr, "Failed to read public key\n"); lock_fail(); return 0; } char dcrpt[BUFSIZ]; if (RSA_public_decrypt(len, b, dcrpt, pub_key, RSA_PKCS1_PADDING) <= 0) { fprintf(stderr, "Failed to decrypt auth file\n"); lock_fail(); return 0; } RSA_free(pub_key); //get executable path char path[BUFSIZ]; int read = readlink("/proc/self/exe", path, BUFSIZ); path[read % BUFSIZ] = '\0'; OpenSSL_add_all_digests(); EVP_MD_CTX mdctx; const EVP_MD *md; unsigned char md_value[EVP_MAX_MD_SIZE]; int md_len, i; md = EVP_get_digestbyname("sha1"); EVP_MD_CTX_init(&mdctx); EVP_DigestInit_ex(&mdctx, md, NULL); FILE *efp = fopen(path, "r"); if (efp == NULL) { fprintf(stderr, "Failed to open executable at %s\n", path); lock_fail(); return 0; } int r = 0; char buf[256]; do { r = fread(buf, sizeof(char), 256, efp); if (read) { EVP_DigestUpdate(&mdctx, buf, r); } } while (r); EVP_DigestFinal_ex(&mdctx, md_value, &md_len); EVP_MD_CTX_cleanup(&mdctx); fclose(efp); char ascisha[BUFSIZ]; for(i = 0; i < md_len; i++) sprintf(&(ascisha[i*2]) , "%02x", md_value[i]); dcrpt[strlen(ascisha)] = '\0'; printf("HASH: %s\n", ascisha); printf("DCPC: %s\n", dcrpt); if (strcmp(ascisha, dcrpt) != 0) { fprintf(stderr, "Failed to autherise, hashes do not match\n"); lock_fail(); return 0; } callable = 1; printf("Verification sucessful\n"); } return 42; }
static long ok_ctrl(BIO *b, int cmd, long num, void *ptr) { BIO_OK_CTX *ctx; EVP_MD *md; const EVP_MD **ppmd; long ret=1; int i; ctx=b->ptr; switch (cmd) { case BIO_CTRL_RESET: ctx->buf_len=0; ctx->buf_off=0; ctx->buf_len_save=0; ctx->buf_off_save=0; ctx->cont=1; ctx->finished=0; ctx->blockout= 0; ctx->sigio=1; ret=BIO_ctrl(b->next_bio,cmd,num,ptr); break; case BIO_CTRL_EOF: /* More to read */ if (ctx->cont <= 0) ret=1; else ret=BIO_ctrl(b->next_bio,cmd,num,ptr); break; case BIO_CTRL_PENDING: /* More to read in buffer */ case BIO_CTRL_WPENDING: /* More to read in buffer */ ret=ctx->blockout ? ctx->buf_len-ctx->buf_off : 0; if (ret <= 0) ret=BIO_ctrl(b->next_bio,cmd,num,ptr); break; case BIO_CTRL_FLUSH: /* do a final write */ if(ctx->blockout == 0) block_out(b); while (ctx->blockout) { i=ok_write(b,NULL,0); if (i < 0) { ret=i; break; } } ctx->finished=1; ctx->buf_off=ctx->buf_len=0; ctx->cont=(int)ret; /* Finally flush the underlying BIO */ ret=BIO_ctrl(b->next_bio,cmd,num,ptr); break; case BIO_C_DO_STATE_MACHINE: BIO_clear_retry_flags(b); ret=BIO_ctrl(b->next_bio,cmd,num,ptr); BIO_copy_next_retry(b); break; case BIO_CTRL_INFO: ret=(long)ctx->cont; break; case BIO_C_SET_MD: md=ptr; EVP_DigestInit_ex(&ctx->md, md, NULL); b->init=1; break; case BIO_C_GET_MD: if (b->init) { ppmd=ptr; *ppmd=ctx->md.digest; } else ret=0; break; default: ret=BIO_ctrl(b->next_bio,cmd,num,ptr); break; } return(ret); }
int ssl3_prf(SSL *s, uint8_t *out, size_t out_len, const uint8_t *secret, size_t secret_len, const char *label, size_t label_len, const uint8_t *seed1, size_t seed1_len, const uint8_t *seed2, size_t seed2_len) { EVP_MD_CTX md5; EVP_MD_CTX sha1; uint8_t buf[16], smd[SHA_DIGEST_LENGTH]; uint8_t c = 'A'; size_t i, j, k; k = 0; EVP_MD_CTX_init(&md5); EVP_MD_CTX_init(&sha1); for (i = 0; i < out_len; i += MD5_DIGEST_LENGTH) { k++; if (k > sizeof(buf)) { /* bug: 'buf' is too small for this ciphersuite */ OPENSSL_PUT_ERROR(SSL, ssl3_prf, ERR_R_INTERNAL_ERROR); return 0; } for (j = 0; j < k; j++) { buf[j] = c; } c++; if (!EVP_DigestInit_ex(&sha1, EVP_sha1(), NULL)) { OPENSSL_PUT_ERROR(SSL, ssl3_prf, ERR_LIB_EVP); return 0; } EVP_DigestUpdate(&sha1, buf, k); EVP_DigestUpdate(&sha1, secret, secret_len); /* |label| is ignored for SSLv3. */ if (seed1_len) { EVP_DigestUpdate(&sha1, seed1, seed1_len); } if (seed2_len) { EVP_DigestUpdate(&sha1, seed2, seed2_len); } EVP_DigestFinal_ex(&sha1, smd, NULL); if (!EVP_DigestInit_ex(&md5, EVP_md5(), NULL)) { OPENSSL_PUT_ERROR(SSL, ssl3_prf, ERR_LIB_EVP); return 0; } EVP_DigestUpdate(&md5, secret, secret_len); EVP_DigestUpdate(&md5, smd, SHA_DIGEST_LENGTH); if (i + MD5_DIGEST_LENGTH > out_len) { EVP_DigestFinal_ex(&md5, smd, NULL); memcpy(out, smd, out_len - i); } else { EVP_DigestFinal_ex(&md5, out, NULL); } out += MD5_DIGEST_LENGTH; } OPENSSL_cleanse(smd, SHA_DIGEST_LENGTH); EVP_MD_CTX_cleanup(&md5); EVP_MD_CTX_cleanup(&sha1); return 1; }
char * caps_create_sha1_str(xmpp_stanza_t * const query) { char *category = NULL; char *type = NULL; char *lang = NULL; char *name = NULL; char *feature_str = NULL; GSList *identities = NULL; GSList *features = NULL; GSList *form_names = NULL; DataForm *form = NULL; FormField *field = NULL; GHashTable *forms = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)stanza_destroy_form); GString *s = g_string_new(""); xmpp_stanza_t *child = xmpp_stanza_get_children(query); while (child != NULL) { if (g_strcmp0(xmpp_stanza_get_name(child), STANZA_NAME_IDENTITY) == 0) { category = xmpp_stanza_get_attribute(child, "category"); type = xmpp_stanza_get_attribute(child, "type"); lang = xmpp_stanza_get_attribute(child, "xml:lang"); name = xmpp_stanza_get_attribute(child, "name"); GString *identity_str = g_string_new(category); g_string_append(identity_str, "/"); if (type != NULL) { g_string_append(identity_str, type); } g_string_append(identity_str, "/"); if (lang != NULL) { g_string_append(identity_str, lang); } g_string_append(identity_str, "/"); if (name != NULL) { g_string_append(identity_str, name); } g_string_append(identity_str, "<"); identities = g_slist_insert_sorted(identities, g_strdup(identity_str->str), (GCompareFunc)strcmp); g_string_free(identity_str, TRUE); } else if (g_strcmp0(xmpp_stanza_get_name(child), STANZA_NAME_FEATURE) == 0) { feature_str = xmpp_stanza_get_attribute(child, "var"); features = g_slist_insert_sorted(features, g_strdup(feature_str), (GCompareFunc)strcmp); } else if (g_strcmp0(xmpp_stanza_get_name(child), STANZA_NAME_X) == 0) { if (strcmp(xmpp_stanza_get_ns(child), STANZA_NS_DATA) == 0) { form = stanza_create_form(child); form_names = g_slist_insert_sorted(form_names, g_strdup(form->form_type), (GCompareFunc)strcmp); g_hash_table_insert(forms, g_strdup(form->form_type), form); } } child = xmpp_stanza_get_next(child); } GSList *curr = identities; while (curr != NULL) { g_string_append(s, curr->data); curr = g_slist_next(curr); } curr = features; while (curr != NULL) { g_string_append(s, curr->data); g_string_append(s, "<"); curr = g_slist_next(curr); } curr = form_names; while (curr != NULL) { form = g_hash_table_lookup(forms, curr->data); g_string_append(s, form->form_type); g_string_append(s, "<"); GSList *curr_field = form->fields; while (curr_field != NULL) { field = curr_field->data; g_string_append(s, field->var); g_string_append(s, "<"); GSList *curr_value = field->values; while (curr_value != NULL) { g_string_append(s, curr_value->data); g_string_append(s, "<"); curr_value = g_slist_next(curr_value); } curr_field = g_slist_next(curr_field); } curr = g_slist_next(curr); } EVP_MD_CTX mdctx; const EVP_MD *md; unsigned char md_value[EVP_MAX_MD_SIZE]; unsigned int md_len; OpenSSL_add_all_digests(); md = EVP_get_digestbyname("SHA1"); EVP_MD_CTX_init(&mdctx); EVP_DigestInit_ex(&mdctx, md, NULL); EVP_DigestUpdate(&mdctx, s->str, strlen(s->str)); EVP_DigestFinal_ex(&mdctx, md_value, &md_len); EVP_MD_CTX_cleanup(&mdctx); char *result = g_base64_encode(md_value, md_len); g_string_free(s, TRUE); g_slist_free_full(identities, g_free); g_slist_free_full(features, g_free); g_slist_free_full(form_names, g_free); g_hash_table_destroy(forms); return result; }
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, *D, *I, *p, *Ai; int Slen, Plen, Ilen, Ijlen; int i, j, u, v; int ret = 0; BIGNUM *Ij, *Bpl1; /* These hold Ij and B + 1 */ EVP_MD_CTX ctx; #ifdef DEBUG_KEYGEN unsigned char *tmpout = out; int tmpn = n; #endif EVP_MD_CTX_init(&ctx); #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 || !Ai || !B || !I || !Ij || !Bpl1) 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_cleanup(&ctx); 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); }
void ssl3_update_handshake_digests( DSSL_Session* sess, u_char* data, uint32_t len ) { DSSL_handshake_buffer *q = NULL, *next; /* sanity check in case client hello is not received */ if( sess->handshake_digest_md5.digest == NULL || sess->handshake_digest_sha.digest == NULL) { ssl3_init_handshake_digests( sess ); } EVP_DigestUpdate( &sess->handshake_digest_md5, data, len ); EVP_DigestUpdate( &sess->handshake_digest_sha, data, len ); if ( sess->version >= TLS1_2_VERSION ) { /* if digest is still unknown, then queue the packets. * we'll calculate the handshake hash once we determine which digest we should use. */ EVP_MD* digest = NULL; DSSL_CipherSuite* suite = sess->dssl_cipher_suite; if ( !suite ) suite = DSSL_GetSSL3CipherSuite( sess->cipher_suite ); digest = EVP_get_digestbyname( suite->digest ); /* 'sha256' is the default for TLS 1.2, and can be replaced with a different (but stronger) hash */ if ( !digest ) { q = (DSSL_handshake_buffer*) malloc( sizeof(DSSL_handshake_buffer) ); q->next = NULL; q->data = (u_char*) malloc( len ); memcpy(q->data, data, len); q->len = len; if (NULL == sess->handshake_queue) sess->handshake_queue = q; else sess->handshake_queue->next = q; DEBUG_TRACE3( "Queue handshake packet %p (%u @ %p)", q, q->len, q->data ); } else if ( digest != sess->handshake_digest.digest && EVP_MD_size( digest ) >= EVP_MD_size( sess->handshake_digest.digest ) ) { /* specified digest is different than the default. * re-init and re-hash all queued packets. */ EVP_MD_CTX_cleanup( &sess->handshake_digest ); EVP_DigestInit_ex( &sess->handshake_digest, digest, NULL ); for (q = sess->handshake_queue; q != NULL; q = next) { DEBUG_TRACE3( "Re-hash handshake packet %p (%u @ %p)", q, q->len, q->data ); EVP_DigestUpdate( &sess->handshake_digest, q->data, q->len ); next = q->next; free ( q->data ); free ( q ); } sess->handshake_queue = NULL; } else { /* specified digest is identical to the default. * throw away all the queued packets. */ for (q = sess->handshake_queue; q != NULL; q = next) { DEBUG_TRACE3( "discard handshake packet %p (%u @ %p)", q, q->len, q->data ); next = q->next; free ( q->data ); free ( q ); } sess->handshake_queue = NULL; } if ( sess->handshake_digest.digest ) EVP_DigestUpdate( &sess->handshake_digest, data, len ); } }
int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, size_t key_len, const EVP_MD *md, ENGINE *impl) { if (md == NULL) { md = ctx->md; } // If either |key| is non-NULL or |md| has changed, initialize with a new key // rather than rewinding the previous one. // // TODO(davidben,eroman): Passing the previous |md| with a NULL |key| is // ambiguous between using the empty key and reusing the previous key. There // exist callers which intend the latter, but the former is an awkward edge // case. Fix to API to avoid this. if (md != ctx->md || key != NULL) { uint8_t pad[EVP_MAX_MD_BLOCK_SIZE]; uint8_t key_block[EVP_MAX_MD_BLOCK_SIZE]; unsigned key_block_len; size_t block_size = EVP_MD_block_size(md); assert(block_size <= sizeof(key_block)); if (block_size < key_len) { // Long keys are hashed. if (!EVP_DigestInit_ex(&ctx->md_ctx, md, impl) || !EVP_DigestUpdate(&ctx->md_ctx, key, key_len) || !EVP_DigestFinal_ex(&ctx->md_ctx, key_block, &key_block_len)) { return 0; } } else { assert(key_len <= sizeof(key_block)); OPENSSL_memcpy(key_block, key, key_len); key_block_len = (unsigned)key_len; } // Keys are then padded with zeros. if (key_block_len != EVP_MAX_MD_BLOCK_SIZE) { OPENSSL_memset(&key_block[key_block_len], 0, sizeof(key_block) - key_block_len); } for (size_t i = 0; i < EVP_MAX_MD_BLOCK_SIZE; i++) { pad[i] = 0x36 ^ key_block[i]; } if (!EVP_DigestInit_ex(&ctx->i_ctx, md, impl) || !EVP_DigestUpdate(&ctx->i_ctx, pad, EVP_MD_block_size(md))) { return 0; } for (size_t i = 0; i < EVP_MAX_MD_BLOCK_SIZE; i++) { pad[i] = 0x5c ^ key_block[i]; } if (!EVP_DigestInit_ex(&ctx->o_ctx, md, impl) || !EVP_DigestUpdate(&ctx->o_ctx, pad, EVP_MD_block_size(md))) { return 0; } ctx->md = md; } if (!EVP_MD_CTX_copy_ex(&ctx->md_ctx, &ctx->i_ctx)) { return 0; } return 1; }
spep::MetadataThread::RawMetadata spep::MetadataThread::getRawMetadata( std::string metadataURL ) { EVP_MD_CTX *hashContext = &(this->_hashContext); // Initialize the hash function for the new metadata. if ( ! EVP_DigestInit_ex( hashContext, this->_hashType, NULL ) ) { throw InvalidStateException( "Unable to initialize the digest function for metadata hashing" ); } RawMetadata data( hashContext ); CArray<char> errorBuffer( CURL_ERROR_SIZE ); std::memset( errorBuffer.get(), 0, CURL_ERROR_SIZE ); _localLogger.debug() << "Calling cURL to retrieve metadata from " << metadataURL; CURL *pCurlHandle = curl_easy_init(); // Set the URL for curl to retrieve from curl_easy_setopt(pCurlHandle, CURLOPT_URL, metadataURL.c_str()); // Give curl something to call with its data curl_easy_setopt(pCurlHandle, CURLOPT_WRITEFUNCTION, spep::MetadataThread::curlCallback); curl_easy_setopt(pCurlHandle, CURLOPT_WRITEDATA, (void*)&data); // Buffer to output an error message if the call fails curl_easy_setopt(pCurlHandle, CURLOPT_ERRORBUFFER, errorBuffer.get()); // Don't give us any content on a HTTP >=400 response curl_easy_setopt(pCurlHandle, CURLOPT_FAILONERROR, 1); // Ignore signals curl_easy_setopt(pCurlHandle, CURLOPT_NOSIGNAL, 1L); // Debugging code curl_easy_setopt(pCurlHandle, CURLOPT_DEBUGFUNCTION, spep::MetadataThread::debugCallback); curl_easy_setopt(pCurlHandle, CURLOPT_DEBUGDATA, (void*)this); curl_easy_setopt(pCurlHandle, CURLOPT_VERBOSE, 1); // Set the CA bundle, if we were given one if( ! this->_caBundle.empty() ) { curl_easy_setopt( pCurlHandle, CURLOPT_CAINFO, this->_caBundle.c_str() ); } // Perform the retrieve operation. This will block until complete. CURLcode result = curl_easy_perform(pCurlHandle); curl_easy_cleanup(pCurlHandle); _localLogger.debug() << boost::lexical_cast<std::string>( result ); // If the request didn't succeed, handle the error condition. if (result != CURLE_OK) { _localLogger.error() << std::string("Metadata retrieve failed. Error message was: ") << errorBuffer.get(); data.failed = true; return data; } data.failed = false; // Finalise the hash unsigned int hashLength = 0; unsigned char hashValue[EVP_MAX_MD_SIZE]; EVP_DigestFinal_ex( hashContext, hashValue, &hashLength ); // .. and build it into a string to be returned in the object. AutoArray<char> hashChars( hashLength*2 + 1 ); for (unsigned int i=0; i<hashLength; ++i) { // Output each byte as 2 hex chars. snprintf( &(hashChars[2*i]), 3, "%02x", hashValue[i] ); } data.hashValue = std::string( hashChars.get(), hashLength*2 ); return data; }
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; }
void QblEvpDigest::init() { EVP_MD_CTX_init(&mdctx); EVP_DigestInit_ex(&mdctx, getAlgorithm(), NULL); }
static isc_result_t opensslrsa_createctx(dst_key_t *key, dst_context_t *dctx) { #if USE_EVP EVP_MD_CTX *evp_md_ctx; const EVP_MD *type = NULL; #endif UNUSED(key); 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); #if USE_EVP evp_md_ctx = EVP_MD_CTX_create(); if (evp_md_ctx == NULL) return (ISC_R_NOMEMORY); switch (dctx->key->key_alg) { case DST_ALG_RSAMD5: type = EVP_md5(); /* MD5 + RSA */ break; case DST_ALG_RSASHA1: case DST_ALG_NSEC3RSASHA1: type = EVP_sha1(); /* SHA1 + RSA */ break; #ifdef HAVE_EVP_SHA256 case DST_ALG_RSASHA256: type = EVP_sha256(); /* SHA256 + RSA */ break; #endif #ifdef HAVE_EVP_SHA512 case DST_ALG_RSASHA512: type = EVP_sha512(); break; #endif default: INSIST(0); } if (!EVP_DigestInit_ex(evp_md_ctx, type, NULL)) { EVP_MD_CTX_destroy(evp_md_ctx); return (dst__openssl_toresult3(dctx->category, "EVP_DigestInit_ex", ISC_R_FAILURE)); } dctx->ctxdata.evp_md_ctx = evp_md_ctx; #else switch (dctx->key->key_alg) { case DST_ALG_RSAMD5: { isc_md5_t *md5ctx; md5ctx = isc_mem_get(dctx->mctx, sizeof(isc_md5_t)); if (md5ctx == NULL) return (ISC_R_NOMEMORY); isc_md5_init(md5ctx); dctx->ctxdata.md5ctx = md5ctx; } break; case DST_ALG_RSASHA1: case DST_ALG_NSEC3RSASHA1: { isc_sha1_t *sha1ctx; sha1ctx = isc_mem_get(dctx->mctx, sizeof(isc_sha1_t)); if (sha1ctx == NULL) return (ISC_R_NOMEMORY); isc_sha1_init(sha1ctx); dctx->ctxdata.sha1ctx = sha1ctx; } break; case DST_ALG_RSASHA256: { isc_sha256_t *sha256ctx; sha256ctx = isc_mem_get(dctx->mctx, sizeof(isc_sha256_t)); if (sha256ctx == NULL) return (ISC_R_NOMEMORY); isc_sha256_init(sha256ctx); dctx->ctxdata.sha256ctx = sha256ctx; } break; case DST_ALG_RSASHA512: { isc_sha512_t *sha512ctx; sha512ctx = isc_mem_get(dctx->mctx, sizeof(isc_sha512_t)); if (sha512ctx == NULL) return (ISC_R_NOMEMORY); isc_sha512_init(sha512ctx); dctx->ctxdata.sha512ctx = sha512ctx; } break; default: INSIST(0); } #endif return (ISC_R_SUCCESS); }
int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash, const EVP_MD *Hash, const EVP_MD *mgf1Hash, const unsigned char *EM, int sLen) { int i; int ret = 0; int hLen, maskedDBLen, MSBits, emLen; const unsigned char *H; unsigned char *DB = NULL; EVP_MD_CTX ctx; unsigned char H_[EVP_MAX_MD_SIZE]; EVP_MD_CTX_init(&ctx); if (mgf1Hash == NULL) mgf1Hash = Hash; hLen = M_EVP_MD_size(Hash); if (hLen < 0) goto err; /* * Negative sLen has special meanings: * -1 sLen == hLen * -2 salt length is autorecovered from signature * -N reserved */ if (sLen == -1) sLen = hLen; else if (sLen == -2) sLen = -2; else if (sLen < -2) { RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED); goto err; } MSBits = (BN_num_bits(rsa->n) - 1) & 0x7; emLen = RSA_size(rsa); if (EM[0] & (0xFF << MSBits)) { RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_FIRST_OCTET_INVALID); goto err; } if (MSBits == 0) { EM++; emLen--; } if (emLen < (hLen + sLen + 2)) /* sLen can be small negative */ { RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_DATA_TOO_LARGE); goto err; } if (EM[emLen - 1] != 0xbc) { RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_LAST_OCTET_INVALID); goto err; } maskedDBLen = emLen - hLen - 1; H = EM + maskedDBLen; DB = OPENSSL_malloc(maskedDBLen); if (!DB) { RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, ERR_R_MALLOC_FAILURE); goto err; } if (PKCS1_MGF1(DB, maskedDBLen, H, hLen, mgf1Hash) < 0) goto err; for (i = 0; i < maskedDBLen; i++) DB[i] ^= EM[i]; if (MSBits) DB[0] &= 0xFF >> (8 - MSBits); for (i = 0; DB[i] == 0 && i < (maskedDBLen-1); i++) ; if (DB[i++] != 0x1) { RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_RECOVERY_FAILED); goto err; } if (sLen >= 0 && (maskedDBLen - i) != sLen) { RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED); goto err; } if (!EVP_DigestInit_ex(&ctx, Hash, NULL) || !EVP_DigestUpdate(&ctx, zeroes, sizeof zeroes) || !EVP_DigestUpdate(&ctx, mHash, hLen)) goto err; if (maskedDBLen - i) { if (!EVP_DigestUpdate(&ctx, DB + i, maskedDBLen - i)) goto err; } if (!EVP_DigestFinal_ex(&ctx, H_, NULL)) goto err; if (memcmp(H_, H, hLen)) { RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_BAD_SIGNATURE); ret = 0; } else ret = 1; err: if (DB) OPENSSL_free(DB); EVP_MD_CTX_cleanup(&ctx); return ret; }
int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type) { EVP_MD_CTX_init(ctx); return EVP_DigestInit_ex(ctx, type, NULL); }