Ejemplo n.º 1
0
/*
 * Generates the mac for the Finished message. Returns the length of the MAC or
 * 0 on error.
 */
size_t tls13_final_finish_mac(SSL *s, const char *str, size_t slen,
                             unsigned char *out)
{
    const EVP_MD *md = ssl_handshake_md(s);
    unsigned char hash[EVP_MAX_MD_SIZE];
    size_t hashlen, ret = 0;
    EVP_PKEY *key = NULL;
    EVP_MD_CTX *ctx = EVP_MD_CTX_new();

    if (!ssl_handshake_hash(s, hash, sizeof(hash), &hashlen))
        goto err;

    if (str == s->method->ssl3_enc->server_finished_label)
        key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
                                   s->server_finished_secret, hashlen);
    else
        key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
                                   s->client_finished_secret, hashlen);

    if (key == NULL
            || ctx == NULL
            || EVP_DigestSignInit(ctx, NULL, md, NULL, key) <= 0
            || EVP_DigestSignUpdate(ctx, hash, hashlen) <= 0
            || EVP_DigestSignFinal(ctx, out, &hashlen) <= 0)
        goto err;

    ret = hashlen;
 err:
    EVP_PKEY_free(key);
    EVP_MD_CTX_free(ctx);
    return ret;
}
Ejemplo n.º 2
0
static int s2n_evp_hmac_p_hash_init(struct s2n_prf_working_space *ws, s2n_hmac_algorithm alg, struct s2n_blob *secret)
{
    /* Initialize the message digest */
    switch (alg) {
    case S2N_HMAC_SSLv3_MD5:
    case S2N_HMAC_MD5:
        ws->tls.p_hash.evp_hmac.evp_digest.md = EVP_md5();
        break;
    case S2N_HMAC_SSLv3_SHA1:
    case S2N_HMAC_SHA1:
        ws->tls.p_hash.evp_hmac.evp_digest.md = EVP_sha1();
        break;
    case S2N_HMAC_SHA224:
        ws->tls.p_hash.evp_hmac.evp_digest.md = EVP_sha224();
        break;
    case S2N_HMAC_SHA256:
        ws->tls.p_hash.evp_hmac.evp_digest.md = EVP_sha256();
        break;
    case S2N_HMAC_SHA384:
        ws->tls.p_hash.evp_hmac.evp_digest.md = EVP_sha384();
        break;
    case S2N_HMAC_SHA512:
        ws->tls.p_hash.evp_hmac.evp_digest.md = EVP_sha512();
        break;
    default:
        S2N_ERROR(S2N_ERR_P_HASH_INVALID_ALGORITHM);
    }

    /* Initialize the mac key using the provided secret */
    notnull_check(ws->tls.p_hash.evp_hmac.mac_key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, secret->data, secret->size));

    /* Initialize the message digest context with the above message digest and mac key */
    return s2n_evp_hmac_p_hash_digest_init(ws);
}
Ejemplo n.º 3
0
SPP_MAC* spp_init_mac_st(SSL* s, SPP_MAC* mac, unsigned char* key, int which) {
    int mac_type;
    EVP_PKEY *mac_key;
    EVP_MD_CTX md;
    const EVP_MD *m;
    
    mac_type = s->s3->tmp.new_mac_pkey_type;
    m=s->s3->tmp.new_hash;
    
    if (mac == NULL) {
        if ((mac=OPENSSL_malloc(sizeof(SPP_MAC))) == NULL) {
            return NULL;
        }
    }
    if (which & SSL3_CC_READ) {
        mac->read_hash = EVP_MD_CTX_create();
        //ssl_replace_hash(&(mac->read_hash),NULL);
        memset(&(mac->read_sequence[0]),0,8);
        mac->read_mac_secret_size = s->s3->tmp.new_mac_secret_size;
        OPENSSL_assert(mac->read_mac_secret_size <= EVP_MAX_MD_SIZE);
        memcpy(&(mac->read_mac_secret[0]), key, mac->read_mac_secret_size);
        mac_key = EVP_PKEY_new_mac_key(mac_type, NULL,&(mac->read_mac_secret[0]),mac->read_mac_secret_size);
        EVP_DigestSignInit(mac->read_hash,NULL,m,NULL,mac_key);
        EVP_PKEY_free(mac_key);
    } else {
        mac->write_hash = EVP_MD_CTX_create();
        //ssl_replace_hash(&(mac->write_hash),NULL);
        memset(&(mac->write_sequence[0]),0,8);
        mac->write_mac_secret_size = s->s3->tmp.new_mac_secret_size;
        OPENSSL_assert(mac->write_mac_secret_size <= EVP_MAX_MD_SIZE);
        memcpy(&(mac->write_mac_secret[0]), key, mac->write_mac_secret_size);
        mac_key = EVP_PKEY_new_mac_key(mac_type, NULL,&(mac->write_mac_secret[0]),mac->write_mac_secret_size);
        EVP_DigestSignInit(mac->write_hash,NULL,m,NULL,mac_key);
        EVP_PKEY_free(mac_key);
    }
    
    return mac;
}
Ejemplo n.º 4
0
int
lws_genhmac_init(struct lws_genhmac_ctx *ctx, enum lws_genhmac_types type,
		 const uint8_t *key, size_t key_len)
{
	EVP_PKEY *pkey;

	ctx->type = type;

	switch (type) {
	case LWS_GENHMAC_TYPE_SHA256:
		ctx->evp_type = EVP_sha256();
		break;
	case LWS_GENHMAC_TYPE_SHA384:
		ctx->evp_type = EVP_sha384();
		break;
	case LWS_GENHMAC_TYPE_SHA512:
		ctx->evp_type = EVP_sha512();
		break;
	default:
		lwsl_err("%s: unknown HMAC type %d\n", __func__, type);
		return -1;
	}

        ctx->ctx = EVP_MD_CTX_create();
        if (!ctx->ctx)
		return -1;

        if (EVP_DigestInit_ex(ctx->ctx, ctx->evp_type, NULL) != 1)
		return -1;

        pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, key, (int)key_len);

        if (EVP_DigestSignInit(ctx->ctx, NULL, ctx->evp_type, NULL, pkey) != 1)
		return -1;

        EVP_PKEY_free(pkey);

	return 0;
}
Ejemplo n.º 5
0
Archivo: dgst.c Proyecto: GH-JY/openssl
int dgst_main(int argc, char **argv)
{
    BIO *in = NULL, *inp, *bmd = NULL, *out = NULL;
    ENGINE *e = NULL, *impl = NULL;
    EVP_PKEY *sigkey = NULL;
    STACK_OF(OPENSSL_STRING) *sigopts = NULL, *macopts = NULL;
    char *hmac_key = NULL;
    char *mac_name = NULL;
    char *passinarg = NULL, *passin = NULL;
    const EVP_MD *md = NULL, *m;
    const char *outfile = NULL, *keyfile = NULL, *prog = NULL;
    const char *sigfile = NULL, *randfile = NULL;
    OPTION_CHOICE o;
    int separator = 0, debug = 0, keyform = FORMAT_PEM, siglen = 0;
    int i, ret = 1, out_bin = -1, want_pub = 0, do_verify =
        0, non_fips_allow = 0;
    unsigned char *buf = NULL, *sigbuf = NULL;
    int engine_impl = 0;

    prog = opt_progname(argv[0]);
    buf = app_malloc(BUFSIZE, "I/O buffer");
    md = EVP_get_digestbyname(prog);

    prog = opt_init(argc, argv, dgst_options);
    while ((o = opt_next()) != OPT_EOF) {
        switch (o) {
        case OPT_EOF:
        case OPT_ERR:
 opthelp:
            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
            goto end;
        case OPT_HELP:
            opt_help(dgst_options);
            ret = 0;
            goto end;
        case OPT_C:
            separator = 1;
            break;
        case OPT_R:
            separator = 2;
            break;
        case OPT_RAND:
            randfile = opt_arg();
            break;
        case OPT_OUT:
            outfile = opt_arg();
            break;
        case OPT_SIGN:
            keyfile = opt_arg();
            break;
        case OPT_PASSIN:
            passinarg = opt_arg();
            break;
        case OPT_VERIFY:
            keyfile = opt_arg();
            want_pub = do_verify = 1;
            break;
        case OPT_PRVERIFY:
            keyfile = opt_arg();
            do_verify = 1;
            break;
        case OPT_SIGNATURE:
            sigfile = opt_arg();
            break;
        case OPT_KEYFORM:
            if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyform))
                goto opthelp;
            break;
        case OPT_ENGINE:
            e = setup_engine(opt_arg(), 0);
            break;
        case OPT_ENGINE_IMPL:
            engine_impl = 1;
            break;
        case OPT_HEX:
            out_bin = 0;
            break;
        case OPT_BINARY:
            out_bin = 1;
            break;
        case OPT_DEBUG:
            debug = 1;
            break;
        case OPT_FIPS_FINGERPRINT:
            hmac_key = "etaonrishdlcupfm";
            break;
        case OPT_NON_FIPS_ALLOW:
            non_fips_allow = 1;
            break;
        case OPT_HMAC:
            hmac_key = opt_arg();
            break;
        case OPT_MAC:
            mac_name = opt_arg();
            break;
        case OPT_SIGOPT:
            if (!sigopts)
                sigopts = sk_OPENSSL_STRING_new_null();
            if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, opt_arg()))
                goto opthelp;
            break;
        case OPT_MACOPT:
            if (!macopts)
                macopts = sk_OPENSSL_STRING_new_null();
            if (!macopts || !sk_OPENSSL_STRING_push(macopts, opt_arg()))
                goto opthelp;
            break;
        case OPT_DIGEST:
            if (!opt_md(opt_unknown(), &m))
                goto opthelp;
            md = m;
            break;
        }
    }
    argc = opt_num_rest();
    argv = opt_rest();

    if (do_verify && !sigfile) {
        BIO_printf(bio_err,
                   "No signature to verify: use the -signature option\n");
        goto end;
    }
    if (engine_impl)
        impl = e;

    in = BIO_new(BIO_s_file());
    bmd = BIO_new(BIO_f_md());
    if ((in == NULL) || (bmd == NULL)) {
        ERR_print_errors(bio_err);
        goto end;
    }

    if (debug) {
        BIO_set_callback(in, BIO_debug_callback);
        /* needed for windows 3.1 */
        BIO_set_callback_arg(in, (char *)bio_err);
    }

    if (!app_passwd(passinarg, NULL, &passin, NULL)) {
        BIO_printf(bio_err, "Error getting password\n");
        goto end;
    }

    if (out_bin == -1) {
        if (keyfile)
            out_bin = 1;
        else
            out_bin = 0;
    }

    if (randfile)
        app_RAND_load_file(randfile, 0);

    out = bio_open_default(outfile, 'w', out_bin ? FORMAT_BINARY : FORMAT_TEXT);
    if (out == NULL)
        goto end;

    if ((! !mac_name + ! !keyfile + ! !hmac_key) > 1) {
        BIO_printf(bio_err, "MAC and Signing key cannot both be specified\n");
        goto end;
    }

    if (keyfile) {
        if (want_pub)
            sigkey = load_pubkey(keyfile, keyform, 0, NULL, e, "key file");
        else
            sigkey = load_key(keyfile, keyform, 0, passin, e, "key file");
        if (!sigkey) {
            /*
             * load_[pub]key() has already printed an appropriate message
             */
            goto end;
        }
    }

    if (mac_name) {
        EVP_PKEY_CTX *mac_ctx = NULL;
        int r = 0;
        if (!init_gen_str(&mac_ctx, mac_name, impl, 0))
            goto mac_end;
        if (macopts) {
            char *macopt;
            for (i = 0; i < sk_OPENSSL_STRING_num(macopts); i++) {
                macopt = sk_OPENSSL_STRING_value(macopts, i);
                if (pkey_ctrl_string(mac_ctx, macopt) <= 0) {
                    BIO_printf(bio_err,
                               "MAC parameter error \"%s\"\n", macopt);
                    ERR_print_errors(bio_err);
                    goto mac_end;
                }
            }
        }
        if (EVP_PKEY_keygen(mac_ctx, &sigkey) <= 0) {
            BIO_puts(bio_err, "Error generating key\n");
            ERR_print_errors(bio_err);
            goto mac_end;
        }
        r = 1;
 mac_end:
        EVP_PKEY_CTX_free(mac_ctx);
        if (r == 0)
            goto end;
    }

    if (non_fips_allow) {
        EVP_MD_CTX *md_ctx;
        BIO_get_md_ctx(bmd, &md_ctx);
        EVP_MD_CTX_set_flags(md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
    }

    if (hmac_key) {
        sigkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, impl,
                                      (unsigned char *)hmac_key, -1);
        if (!sigkey)
            goto end;
    }

    if (sigkey) {
        EVP_MD_CTX *mctx = NULL;
        EVP_PKEY_CTX *pctx = NULL;
        int r;
        if (!BIO_get_md_ctx(bmd, &mctx)) {
            BIO_printf(bio_err, "Error getting context\n");
            ERR_print_errors(bio_err);
            goto end;
        }
        if (do_verify)
            r = EVP_DigestVerifyInit(mctx, &pctx, md, impl, sigkey);
        else
            r = EVP_DigestSignInit(mctx, &pctx, md, impl, sigkey);
        if (!r) {
            BIO_printf(bio_err, "Error setting context\n");
            ERR_print_errors(bio_err);
            goto end;
        }
        if (sigopts) {
            char *sigopt;
            for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) {
                sigopt = sk_OPENSSL_STRING_value(sigopts, i);
                if (pkey_ctrl_string(pctx, sigopt) <= 0) {
                    BIO_printf(bio_err, "parameter error \"%s\"\n", sigopt);
                    ERR_print_errors(bio_err);
                    goto end;
                }
            }
        }
    }
    /* we use md as a filter, reading from 'in' */
    else {
        EVP_MD_CTX *mctx = NULL;
        if (!BIO_get_md_ctx(bmd, &mctx)) {
            BIO_printf(bio_err, "Error getting context\n");
            ERR_print_errors(bio_err);
            goto end;
        }
        if (md == NULL)
            md = EVP_md5();
        if (!EVP_DigestInit_ex(mctx, md, impl)) {
            BIO_printf(bio_err, "Error setting digest\n");
            ERR_print_errors(bio_err);
            goto end;
        }
    }

    if (sigfile && sigkey) {
        BIO *sigbio = BIO_new_file(sigfile, "rb");
        if (!sigbio) {
            BIO_printf(bio_err, "Error opening signature file %s\n", sigfile);
            ERR_print_errors(bio_err);
            goto end;
        }
        siglen = EVP_PKEY_size(sigkey);
        sigbuf = app_malloc(siglen, "signature buffer");
        siglen = BIO_read(sigbio, sigbuf, siglen);
        BIO_free(sigbio);
        if (siglen <= 0) {
            BIO_printf(bio_err, "Error reading signature file %s\n", sigfile);
            ERR_print_errors(bio_err);
            goto end;
        }
    }
    inp = BIO_push(bmd, in);

    if (md == NULL) {
        EVP_MD_CTX *tctx;
        BIO_get_md_ctx(bmd, &tctx);
        md = EVP_MD_CTX_md(tctx);
    }

    if (argc == 0) {
        BIO_set_fp(in, stdin, BIO_NOCLOSE);
        ret = do_fp(out, buf, inp, separator, out_bin, sigkey, sigbuf,
                    siglen, NULL, NULL, "stdin", bmd);
    } else {
        const char *md_name = NULL, *sig_name = NULL;
        if (!out_bin) {
            if (sigkey) {
                const EVP_PKEY_ASN1_METHOD *ameth;
                ameth = EVP_PKEY_get0_asn1(sigkey);
                if (ameth)
                    EVP_PKEY_asn1_get0_info(NULL, NULL,
                                            NULL, NULL, &sig_name, ameth);
            }
            if (md)
                md_name = EVP_MD_name(md);
        }
        ret = 0;
        for (i = 0; i < argc; i++) {
            int r;
            if (BIO_read_filename(in, argv[i]) <= 0) {
                perror(argv[i]);
                ret++;
                continue;
            } else
                r = do_fp(out, buf, inp, separator, out_bin, sigkey, sigbuf,
                          siglen, sig_name, md_name, argv[i], bmd);
            if (r)
                ret = r;
            (void)BIO_reset(bmd);
        }
    }
 end:
    OPENSSL_clear_free(buf, BUFSIZE);
    BIO_free(in);
    OPENSSL_free(passin);
    BIO_free_all(out);
    EVP_PKEY_free(sigkey);
    sk_OPENSSL_STRING_free(sigopts);
    sk_OPENSSL_STRING_free(macopts);
    OPENSSL_free(sigbuf);
    BIO_free(bmd);
    return (ret);
}
Ejemplo n.º 6
0
int tls1_change_cipher_state(SSL *s, int which)
	{
	static const unsigned char empty[]="";
	unsigned char *p,*mac_secret;
	unsigned char *exp_label;
	unsigned char tmp1[EVP_MAX_KEY_LENGTH];
	unsigned char tmp2[EVP_MAX_KEY_LENGTH];
	unsigned char iv1[EVP_MAX_IV_LENGTH*2];
	unsigned char iv2[EVP_MAX_IV_LENGTH*2];
	unsigned char *ms,*key,*iv;
	int client_write;
	EVP_CIPHER_CTX *dd;
	const EVP_CIPHER *c;
#ifndef OPENSSL_NO_COMP
	const SSL_COMP *comp;
#endif
	const EVP_MD *m;
	int mac_type;
	int *mac_secret_size;
	EVP_MD_CTX *mac_ctx;
	EVP_PKEY *mac_key;
	int is_export,n,i,j,k,exp_label_len,cl;
	int reuse_dd = 0;

	is_export=SSL_C_IS_EXPORT(s->s3->tmp.new_cipher);
	c=s->s3->tmp.new_sym_enc;
	m=s->s3->tmp.new_hash;
	mac_type = s->s3->tmp.new_mac_pkey_type;
#ifndef OPENSSL_NO_COMP
	comp=s->s3->tmp.new_compression;
#endif

#ifdef KSSL_DEBUG
	TINYCLR_SSL_PRINTF("tls1_change_cipher_state(which= %d) w/\n", which);
	TINYCLR_SSL_PRINTF("\talg= %ld/%ld, comp= %p\n",
	       s->s3->tmp.new_cipher->algorithm_mkey,
	       s->s3->tmp.new_cipher->algorithm_auth,
	       comp);
	TINYCLR_SSL_PRINTF("\tevp_cipher == %p ==? &d_cbc_ede_cipher3\n", c);
	TINYCLR_SSL_PRINTF("\tevp_cipher: nid, blksz= %d, %d, keylen=%d, ivlen=%d\n",
                c->nid,c->block_size,c->key_len,c->iv_len);
	TINYCLR_SSL_PRINTF("\tkey_block: len= %d, data= ", s->s3->tmp.key_block_length);
	{
        int i;
        for (i=0; i<s->s3->tmp.key_block_length; i++)
		TINYCLR_SSL_PRINTF("%02x", key_block[i]);  TINYCLR_SSL_PRINTF("\n");
        }
#endif	/* KSSL_DEBUG */

	if (which & SSL3_CC_READ)
		{
		if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC)
			s->mac_flags |= SSL_MAC_FLAG_READ_MAC_STREAM;
			else
			s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM;

		if (s->enc_read_ctx != NULL)
			reuse_dd = 1;
		else if ((s->enc_read_ctx=(EVP_CIPHER_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;
		mac_ctx=ssl_replace_hash(&s->read_hash,NULL);
#ifndef OPENSSL_NO_COMP
		if (s->expand != NULL)
			{
			COMP_CTX_free(s->expand);
			s->expand=NULL;
			}
		if (comp != NULL)
			{
			s->expand=COMP_CTX_new(comp->method);
			if (s->expand == NULL)
				{
				SSLerr(SSL_F_TLS1_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_ENCRYPTED_LENGTH);
			if (s->s3->rrec.comp == NULL)
				goto err;
			}
#endif
		/* this is done by dtls1_reset_seq_numbers for DTLS1_VERSION */
 		if (s->version != DTLS1_VERSION)
			TINYCLR_SSL_MEMSET(&(s->s3->read_sequence[0]),0,8);
		mac_secret= &(s->s3->read_mac_secret[0]);
		mac_secret_size=&(s->s3->read_mac_secret_size);
		}
	else
		{
		if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC)
			s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM;
			else
			s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM;
		if (s->enc_write_ctx != NULL)
			reuse_dd = 1;
		else if ((s->enc_write_ctx=(EVP_CIPHER_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;
		mac_ctx = ssl_replace_hash(&s->write_hash,NULL);
#ifndef OPENSSL_NO_COMP
		if (s->compress != NULL)
			{
			COMP_CTX_free(s->compress);
			s->compress=NULL;
			}
		if (comp != NULL)
			{
			s->compress=COMP_CTX_new(comp->method);
			if (s->compress == NULL)
				{
				SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR);
				goto err2;
				}
			}
#endif
		/* this is done by dtls1_reset_seq_numbers for DTLS1_VERSION */
 		if (s->version != DTLS1_VERSION)
			TINYCLR_SSL_MEMSET(&(s->s3->write_sequence[0]),0,8);
		mac_secret= &(s->s3->write_mac_secret[0]);
		mac_secret_size = &(s->s3->write_mac_secret_size);
		}

	if (reuse_dd)
		EVP_CIPHER_CTX_cleanup(dd);

	p=s->s3->tmp.key_block;
	i=*mac_secret_size=s->s3->tmp.new_mac_secret_size;

	cl=EVP_CIPHER_key_length(c);
	j=is_export ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ?
	               cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl;
	/* Was j=(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;
		exp_label=(unsigned char *)TLS_MD_CLIENT_WRITE_KEY_CONST;
		exp_label_len=TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE;
		client_write=1;
		}
	else
		{
		n=i;
		ms=  &(p[ n]); n+=i+j;
		key= &(p[ n]); n+=j+k;
		iv=  &(p[ n]); n+=k;
		exp_label=(unsigned char *)TLS_MD_SERVER_WRITE_KEY_CONST;
		exp_label_len=TLS_MD_SERVER_WRITE_KEY_CONST_SIZE;
		client_write=0;
		}

	if (n > s->s3->tmp.key_block_length)
		{
		SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,ERR_R_INTERNAL_ERROR);
		goto err2;
		}

	TINYCLR_SSL_MEMCPY(mac_secret,ms,i);
	mac_key = EVP_PKEY_new_mac_key(mac_type, NULL,
			mac_secret,*mac_secret_size);
	EVP_DigestSignInit(mac_ctx,NULL,m,NULL,mac_key);
	EVP_PKEY_free(mac_key);
#ifdef TLS_DEBUG
TINYCLR_SSL_PRINTF("which = %04X\nmac key=",which);
{ int z; for (z=0; z<i; z++) TINYCLR_SSL_PRINTF("%02X%c",ms[z],((z+1)%16)?' ':'\n'); }
#endif
	if (is_export)
		{
		/* In here I set both the read and write key/iv to the
		 * same value since only the correct one will be used :-).
		 */
		if (!tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
				exp_label,exp_label_len,
				s->s3->client_random,SSL3_RANDOM_SIZE,
				s->s3->server_random,SSL3_RANDOM_SIZE,
				NULL,0,NULL,0,
				key,j,tmp1,tmp2,EVP_CIPHER_key_length(c)))
			goto err2;
		key=tmp1;

		if (k > 0)
			{
			if (!tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
					TLS_MD_IV_BLOCK_CONST,TLS_MD_IV_BLOCK_CONST_SIZE,
					s->s3->client_random,SSL3_RANDOM_SIZE,
					s->s3->server_random,SSL3_RANDOM_SIZE,
					NULL,0,NULL,0,
					empty,0,iv1,iv2,k*2))
				goto err2;
			if (client_write)
				iv=iv1;
			else
				iv= &(iv1[k]);
			}
		}

	s->session->key_arg_length=0;
#ifdef KSSL_DEBUG
	{
        int i;
	TINYCLR_SSL_PRINTF("EVP_CipherInit_ex(dd,c,key=,iv=,which)\n");
	TINYCLR_SSL_PRINTF("\tkey= "); for (i=0; i<c->key_len; i++) TINYCLR_SSL_PRINTF("%02x", key[i]);
	TINYCLR_SSL_PRINTF("\n");
	TINYCLR_SSL_PRINTF("\t iv= "); for (i=0; i<c->iv_len; i++) TINYCLR_SSL_PRINTF("%02x", iv[i]);
	TINYCLR_SSL_PRINTF("\n");
	}
#endif	/* KSSL_DEBUG */

	EVP_CipherInit_ex(dd,c,NULL,key,iv,(which & SSL3_CC_WRITE));
#ifdef TLS_DEBUG
TINYCLR_SSL_PRINTF("which = %04X\nkey=",which);
{ int z; for (z=0; z<EVP_CIPHER_key_length(c); z++) TINYCLR_SSL_PRINTF("%02X%c",key[z],((z+1)%16)?' ':'\n'); }
TINYCLR_SSL_PRINTF("\niv=");
{ int z; for (z=0; z<k; z++) TINYCLR_SSL_PRINTF("%02X%c",iv[z],((z+1)%16)?' ':'\n'); }
TINYCLR_SSL_PRINTF("\n");
#endif

	OPENSSL_cleanse(tmp1,sizeof(tmp1));
	OPENSSL_cleanse(tmp2,sizeof(tmp1));
	OPENSSL_cleanse(iv1,sizeof(iv1));
	OPENSSL_cleanse(iv2,sizeof(iv2));
	return(1);
err:
	SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,ERR_R_MALLOC_FAILURE);
err2:
	return(0);
	}
Ejemplo n.º 7
0
int
dgst_main(int argc, char **argv)
{
	ENGINE *e = NULL;
	unsigned char *buf = NULL;
	int i, err = 1;
	const EVP_MD *md = NULL, *m;
	BIO *in = NULL, *inp;
	BIO *bmd = NULL;
	BIO *out = NULL;
#define PROG_NAME_SIZE  39
	char pname[PROG_NAME_SIZE + 1];
	int separator = 0;
	int debug = 0;
	int keyform = FORMAT_PEM;
	const char *outfile = NULL, *keyfile = NULL;
	const char *sigfile = NULL;
	int out_bin = -1, want_pub = 0, do_verify = 0;
	EVP_PKEY *sigkey = NULL;
	unsigned char *sigbuf = NULL;
	int siglen = 0;
	char *passargin = NULL, *passin = NULL;
#ifndef OPENSSL_NO_ENGINE
	char *engine = NULL;
#endif
	char *hmac_key = NULL;
	char *mac_name = NULL;
	STACK_OF(OPENSSL_STRING) * sigopts = NULL, *macopts = NULL;

	if ((buf = malloc(BUFSIZE)) == NULL) {
		BIO_printf(bio_err, "out of memory\n");
		goto end;
	}

	/* first check the program name */
	program_name(argv[0], pname, sizeof pname);

	md = EVP_get_digestbyname(pname);

	argc--;
	argv++;
	while (argc > 0) {
		if ((*argv)[0] != '-')
			break;
		if (strcmp(*argv, "-c") == 0)
			separator = 1;
		else if (strcmp(*argv, "-r") == 0)
			separator = 2;
		else if (strcmp(*argv, "-out") == 0) {
			if (--argc < 1)
				break;
			outfile = *(++argv);
		} else if (strcmp(*argv, "-sign") == 0) {
			if (--argc < 1)
				break;
			keyfile = *(++argv);
		} else if (!strcmp(*argv, "-passin")) {
			if (--argc < 1)
				break;
			passargin = *++argv;
		} else if (strcmp(*argv, "-verify") == 0) {
			if (--argc < 1)
				break;
			keyfile = *(++argv);
			want_pub = 1;
			do_verify = 1;
		} else if (strcmp(*argv, "-prverify") == 0) {
			if (--argc < 1)
				break;
			keyfile = *(++argv);
			do_verify = 1;
		} else if (strcmp(*argv, "-signature") == 0) {
			if (--argc < 1)
				break;
			sigfile = *(++argv);
		} else if (strcmp(*argv, "-keyform") == 0) {
			if (--argc < 1)
				break;
			keyform = str2fmt(*(++argv));
		}
#ifndef OPENSSL_NO_ENGINE
		else if (strcmp(*argv, "-engine") == 0) {
			if (--argc < 1)
				break;
			engine = *(++argv);
			e = setup_engine(bio_err, engine, 0);
		}
#endif
		else if (strcmp(*argv, "-hex") == 0)
			out_bin = 0;
		else if (strcmp(*argv, "-binary") == 0)
			out_bin = 1;
		else if (strcmp(*argv, "-d") == 0)
			debug = 1;
		else if (!strcmp(*argv, "-hmac")) {
			if (--argc < 1)
				break;
			hmac_key = *++argv;
		} else if (!strcmp(*argv, "-mac")) {
			if (--argc < 1)
				break;
			mac_name = *++argv;
		} else if (strcmp(*argv, "-sigopt") == 0) {
			if (--argc < 1)
				break;
			if (!sigopts)
				sigopts = sk_OPENSSL_STRING_new_null();
			if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv)))
				break;
		} else if (strcmp(*argv, "-macopt") == 0) {
			if (--argc < 1)
				break;
			if (!macopts)
				macopts = sk_OPENSSL_STRING_new_null();
			if (!macopts || !sk_OPENSSL_STRING_push(macopts, *(++argv)))
				break;
		} else if ((m = EVP_get_digestbyname(&((*argv)[1]))) != NULL)
			md = m;
		else
			break;
		argc--;
		argv++;
	}


	if (do_verify && !sigfile) {
		BIO_printf(bio_err, "No signature to verify: use the -signature option\n");
		goto end;
	}
	if ((argc > 0) && (argv[0][0] == '-')) {	/* bad option */
		BIO_printf(bio_err, "unknown option '%s'\n", *argv);
		BIO_printf(bio_err, "options are\n");
		BIO_printf(bio_err, "-c              to output the digest with separating colons\n");
		BIO_printf(bio_err, "-r              to output the digest in coreutils format\n");
		BIO_printf(bio_err, "-d              to output debug info\n");
		BIO_printf(bio_err, "-hex            output as hex dump\n");
		BIO_printf(bio_err, "-binary         output in binary form\n");
		BIO_printf(bio_err, "-sign   file    sign digest using private key in file\n");
		BIO_printf(bio_err, "-verify file    verify a signature using public key in file\n");
		BIO_printf(bio_err, "-prverify file  verify a signature using private key in file\n");
		BIO_printf(bio_err, "-keyform arg    key file format (PEM or ENGINE)\n");
		BIO_printf(bio_err, "-out filename   output to filename rather than stdout\n");
		BIO_printf(bio_err, "-signature file signature to verify\n");
		BIO_printf(bio_err, "-sigopt nm:v    signature parameter\n");
		BIO_printf(bio_err, "-hmac key       create hashed MAC with key\n");
		BIO_printf(bio_err, "-mac algorithm  create MAC (not neccessarily HMAC)\n");
		BIO_printf(bio_err, "-macopt nm:v    MAC algorithm parameters or key\n");
#ifndef OPENSSL_NO_ENGINE
		BIO_printf(bio_err, "-engine e       use engine e, possibly a hardware device.\n");
#endif

		EVP_MD_do_all_sorted(list_md_fn, bio_err);
		goto end;
	}

	in = BIO_new(BIO_s_file());
	bmd = BIO_new(BIO_f_md());
	if (in == NULL || bmd == NULL) {
		ERR_print_errors(bio_err);
		goto end;
	}

	if (debug) {
		BIO_set_callback(in, BIO_debug_callback);
		/* needed for windows 3.1 */
		BIO_set_callback_arg(in, (char *) bio_err);
	}
	if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) {
		BIO_printf(bio_err, "Error getting password\n");
		goto end;
	}
	if (out_bin == -1) {
		if (keyfile)
			out_bin = 1;
		else
			out_bin = 0;
	}

	if (outfile) {
		if (out_bin)
			out = BIO_new_file(outfile, "wb");
		else
			out = BIO_new_file(outfile, "w");
	} else {
		out = BIO_new_fp(stdout, BIO_NOCLOSE);
	}

	if (!out) {
		BIO_printf(bio_err, "Error opening output file %s\n",
		    outfile ? outfile : "(stdout)");
		ERR_print_errors(bio_err);
		goto end;
	}
	if ((!!mac_name + !!keyfile + !!hmac_key) > 1) {
		BIO_printf(bio_err, "MAC and Signing key cannot both be specified\n");
		goto end;
	}
	if (keyfile) {
		if (want_pub)
			sigkey = load_pubkey(bio_err, keyfile, keyform, 0, NULL,
			    e, "key file");
		else
			sigkey = load_key(bio_err, keyfile, keyform, 0, passin,
			    e, "key file");
		if (!sigkey) {
			/*
			 * load_[pub]key() has already printed an appropriate
			 * message
			 */
			goto end;
		}
	}
	if (mac_name) {
		EVP_PKEY_CTX *mac_ctx = NULL;
		int r = 0;
		if (!init_gen_str(bio_err, &mac_ctx, mac_name, e, 0))
			goto mac_end;
		if (macopts) {
			char *macopt;
			for (i = 0; i < sk_OPENSSL_STRING_num(macopts); i++) {
				macopt = sk_OPENSSL_STRING_value(macopts, i);
				if (pkey_ctrl_string(mac_ctx, macopt) <= 0) {
					BIO_printf(bio_err,
					    "MAC parameter error \"%s\"\n",
					    macopt);
					ERR_print_errors(bio_err);
					goto mac_end;
				}
			}
		}
		if (EVP_PKEY_keygen(mac_ctx, &sigkey) <= 0) {
			BIO_puts(bio_err, "Error generating key\n");
			ERR_print_errors(bio_err);
			goto mac_end;
		}
		r = 1;
mac_end:
		if (mac_ctx)
			EVP_PKEY_CTX_free(mac_ctx);
		if (r == 0)
			goto end;
	}
	if (hmac_key) {
		sigkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, e,
		    (unsigned char *) hmac_key, -1);
		if (!sigkey)
			goto end;
	}
	if (sigkey) {
		EVP_MD_CTX *mctx = NULL;
		EVP_PKEY_CTX *pctx = NULL;
		int r;
		if (!BIO_get_md_ctx(bmd, &mctx)) {
			BIO_printf(bio_err, "Error getting context\n");
			ERR_print_errors(bio_err);
			goto end;
		}
		if (do_verify)
			r = EVP_DigestVerifyInit(mctx, &pctx, md, NULL, sigkey);
		else
			r = EVP_DigestSignInit(mctx, &pctx, md, NULL, sigkey);
		if (!r) {
			BIO_printf(bio_err, "Error setting context\n");
			ERR_print_errors(bio_err);
			goto end;
		}
		if (sigopts) {
			char *sigopt;
			for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) {
				sigopt = sk_OPENSSL_STRING_value(sigopts, i);
				if (pkey_ctrl_string(pctx, sigopt) <= 0) {
					BIO_printf(bio_err,
					    "parameter error \"%s\"\n",
					    sigopt);
					ERR_print_errors(bio_err);
					goto end;
				}
			}
		}
	}
	/* we use md as a filter, reading from 'in' */
	else {
		if (md == NULL)
			md = EVP_md5();
		if (!BIO_set_md(bmd, md)) {
			BIO_printf(bio_err, "Error setting digest %s\n", pname);
			ERR_print_errors(bio_err);
			goto end;
		}
	}

	if (sigfile && sigkey) {
		BIO *sigbio;
		siglen = EVP_PKEY_size(sigkey);
		sigbuf = malloc(siglen);
		if (sigbuf == NULL) {
			BIO_printf(bio_err, "out of memory\n");
			ERR_print_errors(bio_err);
			goto end;
		}
		sigbio = BIO_new_file(sigfile, "rb");
		if (!sigbio) {
			BIO_printf(bio_err, "Error opening signature file %s\n",
			    sigfile);
			ERR_print_errors(bio_err);
			goto end;
		}
		siglen = BIO_read(sigbio, sigbuf, siglen);
		BIO_free(sigbio);
		if (siglen <= 0) {
			BIO_printf(bio_err, "Error reading signature file %s\n",
			    sigfile);
			ERR_print_errors(bio_err);
			goto end;
		}
	}
	inp = BIO_push(bmd, in);

	if (md == NULL) {
		EVP_MD_CTX *tctx;
		BIO_get_md_ctx(bmd, &tctx);
		md = EVP_MD_CTX_md(tctx);
	}
	if (argc == 0) {
		BIO_set_fp(in, stdin, BIO_NOCLOSE);
		err = do_fp(out, buf, inp, separator, out_bin, sigkey, sigbuf,
		    siglen, NULL, NULL, "stdin", bmd);
	} else {
		const char *md_name = NULL, *sig_name = NULL;
		if (!out_bin) {
			if (sigkey) {
				const EVP_PKEY_ASN1_METHOD *ameth;
				ameth = EVP_PKEY_get0_asn1(sigkey);
				if (ameth)
					EVP_PKEY_asn1_get0_info(NULL, NULL,
					    NULL, NULL, &sig_name, ameth);
			}
			md_name = EVP_MD_name(md);
		}
		err = 0;
		for (i = 0; i < argc; i++) {
			int r;
			if (BIO_read_filename(in, argv[i]) <= 0) {
				perror(argv[i]);
				err++;
				continue;
			} else {
				r = do_fp(out, buf, inp, separator, out_bin,
				    sigkey, sigbuf, siglen, sig_name, md_name,
				    argv[i], bmd);
			}
			if (r)
				err = r;
			(void) BIO_reset(bmd);
		}
	}

end:
	if (buf != NULL) {
		OPENSSL_cleanse(buf, BUFSIZE);
		free(buf);
	}
	if (in != NULL)
		BIO_free(in);
	free(passin);
	BIO_free_all(out);
	EVP_PKEY_free(sigkey);
	if (sigopts)
		sk_OPENSSL_STRING_free(sigopts);
	if (macopts)
		sk_OPENSSL_STRING_free(macopts);
	free(sigbuf);
	if (bmd != NULL)
		BIO_free(bmd);

	return (err);
}
Ejemplo n.º 8
0
/* seed1 through seed5 are virtually concatenated */
static int tls1_P_hash(const EVP_MD *md, const unsigned char *sec,
			int sec_len,
			const void *seed1, int seed1_len,
			const void *seed2, int seed2_len,
			const void *seed3, int seed3_len,
			const void *seed4, int seed4_len,
			const void *seed5, int seed5_len,
			unsigned char *out, int olen)
	{
	int chunk;
	size_t j;
	EVP_MD_CTX ctx, ctx_tmp;
	EVP_PKEY *mac_key;
	unsigned char A1[EVP_MAX_MD_SIZE];
	size_t A1_len;
	int ret = 0;
	
	chunk=EVP_MD_size(md);
	OPENSSL_assert(chunk >= 0);

	EVP_MD_CTX_init(&ctx);
	EVP_MD_CTX_init(&ctx_tmp);
	EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
	EVP_MD_CTX_set_flags(&ctx_tmp, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
	mac_key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, sec, sec_len);
	if (!mac_key)
		goto err;
	if (!EVP_DigestSignInit(&ctx,NULL,md, NULL, mac_key))
		goto err;
	if (!EVP_DigestSignInit(&ctx_tmp,NULL,md, NULL, mac_key))
		goto err;
	if (seed1 && !EVP_DigestSignUpdate(&ctx,seed1,seed1_len))
		goto err;
	if (seed2 && !EVP_DigestSignUpdate(&ctx,seed2,seed2_len))
		goto err;
	if (seed3 && !EVP_DigestSignUpdate(&ctx,seed3,seed3_len))
		goto err;
	if (seed4 && !EVP_DigestSignUpdate(&ctx,seed4,seed4_len))
		goto err;
	if (seed5 && !EVP_DigestSignUpdate(&ctx,seed5,seed5_len))
		goto err;
	if (!EVP_DigestSignFinal(&ctx,A1,&A1_len))
		goto err;

	for (;;)
		{
		/* Reinit mac contexts */
		if (!EVP_DigestSignInit(&ctx,NULL,md, NULL, mac_key))
			goto err;
		if (!EVP_DigestSignInit(&ctx_tmp,NULL,md, NULL, mac_key))
			goto err;
		if (!EVP_DigestSignUpdate(&ctx,A1,A1_len))
			goto err;
		if (!EVP_DigestSignUpdate(&ctx_tmp,A1,A1_len))
			goto err;
		if (seed1 && !EVP_DigestSignUpdate(&ctx,seed1,seed1_len))
			goto err;
		if (seed2 && !EVP_DigestSignUpdate(&ctx,seed2,seed2_len))
			goto err;
		if (seed3 && !EVP_DigestSignUpdate(&ctx,seed3,seed3_len))
			goto err;
		if (seed4 && !EVP_DigestSignUpdate(&ctx,seed4,seed4_len))
			goto err;
		if (seed5 && !EVP_DigestSignUpdate(&ctx,seed5,seed5_len))
			goto err;

		if (olen > chunk)
			{
			if (!EVP_DigestSignFinal(&ctx,out,&j))
				goto err;
			out+=j;
			olen-=j;
			/* calc the next A1 value */
			if (!EVP_DigestSignFinal(&ctx_tmp,A1,&A1_len))
				goto err;
			}
		else	/* last one */
			{
			if (!EVP_DigestSignFinal(&ctx,A1,&A1_len))
				goto err;
			memcpy(out,A1,olen);
			break;
			}
		}
	ret = 1;
err:
	EVP_PKEY_free(mac_key);
	EVP_MD_CTX_cleanup(&ctx);
	EVP_MD_CTX_cleanup(&ctx_tmp);
	OPENSSL_cleanse(A1,sizeof(A1));
	return ret;
	}