Exemplo n.º 1
0
int
ssh_dss_sign(const Key *key, u_char **sigp, u_int *lenp,
    const u_char *data, u_int datalen)
{
  const int datafellows = CoreConnection::current ()
    .datafellows ();

	DSA_SIG *sig;
	const EVP_MD *evp_md = EVP_sha1();
	EVP_MD_CTX md;
	u_char digest[EVP_MAX_MD_SIZE], sigblob[SIGBLOB_LEN];
	u_int rlen, slen, len, dlen;
	Buffer b;

	if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) {
		error("ssh_dss_sign: no DSA key");
		return -1;
	}
	EVP_DigestInit(&md, evp_md);
	EVP_DigestUpdate(&md, data, datalen);
	EVP_DigestFinal(&md, digest, &dlen);

	sig = DSA_do_sign(digest, dlen, key->dsa);
	memset(digest, 'd', sizeof(digest));

	if (sig == NULL) {
		error("ssh_dss_sign: sign failed");
		return -1;
	}

	rlen = BN_num_bytes(sig->r);
	slen = BN_num_bytes(sig->s);
	if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) {
		error("bad sig size %u %u", rlen, slen);
		DSA_SIG_free(sig);
		return -1;
	}
	memset(sigblob, 0, SIGBLOB_LEN);
	BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen);
	BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen);
	DSA_SIG_free(sig);

	if (datafellows & SSH_BUG_SIGBLOB) {
		if (lenp != NULL)
			*lenp = SIGBLOB_LEN;
		if (sigp != NULL) {
			*sigp = (u_char*) xmalloc(SIGBLOB_LEN);
			memcpy(*sigp, sigblob, SIGBLOB_LEN);
		}
	} else {
		/* ietf-drafts */
		buffer_init(&b);
		buffer_put_cstring(&b, "ssh-dss");
		buffer_put_string(&b, sigblob, SIGBLOB_LEN);
		len = buffer_len(&b);
		if (lenp != NULL)
			*lenp = len;
		if (sigp != NULL) {
			*sigp = (u_char*) xmalloc(len);
			memcpy(*sigp, buffer_ptr(&b), len);
		}
		buffer_free(&b);
	}
	return 0;
}
Exemplo n.º 2
0
int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t len) {
  return EVP_DigestUpdate(ctx, data, len);
}
Exemplo n.º 3
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 = type->key_len;
    niv = type->iv_len;
    OPENSSL_assert(nkey <= EVP_MAX_KEY_LENGTH);
    OPENSSL_assert(niv <= EVP_MAX_IV_LENGTH);

    if (data == NULL)
        return (nkey);

    EVP_MD_CTX_init(&c);
    for (;;) {
        if (!EVP_DigestInit_ex(&c, md, NULL))
            goto err;
        if (addmd++)
            if (!EVP_DigestUpdate(&c, &(md_buf[0]), mds))
                goto err;
        if (!EVP_DigestUpdate(&c, data, datal))
            goto err;
        if (salt != NULL)
            if (!EVP_DigestUpdate(&c, salt, PKCS5_SALT_LEN))
                goto err;
        if (!EVP_DigestFinal_ex(&c, &(md_buf[0]), &mds))
            goto err;

        for (i = 1; i < (unsigned int)count; i++) {
            if (!EVP_DigestInit_ex(&c, md, NULL))
                goto err;
            if (!EVP_DigestUpdate(&c, &(md_buf[0]), mds))
                goto err;
            if (!EVP_DigestFinal_ex(&c, &(md_buf[0]), &mds))
                goto err;
        }
        i = 0;
        if (nkey) {
            for (;;) {
                if (nkey == 0)
                    break;
                if (i == mds)
                    break;
                if (key != NULL)
                    *(key++) = md_buf[i];
                nkey--;
                i++;
            }
        }
        if (niv && (i != mds)) {
            for (;;) {
                if (niv == 0)
                    break;
                if (i == mds)
                    break;
                if (iv != NULL)
                    *(iv++) = md_buf[i];
                niv--;
                i++;
            }
        }
        if ((nkey == 0) && (niv == 0))
            break;
    }
    rv = type->key_len;
 err:
    EVP_MD_CTX_cleanup(&c);
    OPENSSL_cleanse(md_buf, sizeof(md_buf));
    return rv;
}
Exemplo n.º 4
0
void DigestEngine::updateImpl(const void* data, std::size_t length)
{
	EVP_DigestUpdate(_pContext, data, length);
}
Exemplo n.º 5
0
SM2_CIPHERTEXT_VALUE *SM2_do_encrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
	const unsigned char *in, size_t inlen, EC_KEY *ec_key)
{
	int ok = 0;
	SM2_CIPHERTEXT_VALUE *cv = NULL;
	const EC_GROUP *ec_group = EC_KEY_get0_group(ec_key);
	const EC_POINT *pub_key = EC_KEY_get0_public_key(ec_key);
	KDF_FUNC kdf = KDF_get_x9_63(kdf_md);
	EC_POINT *point = NULL;
	BIGNUM *n = NULL;
	BIGNUM *h = NULL;
	BIGNUM *k = NULL;
	BN_CTX *bn_ctx = NULL;
	EVP_MD_CTX *md_ctx = NULL;
	unsigned char buf[(OPENSSL_ECC_MAX_FIELD_BITS + 7)/4 + 1];
	int nbytes;
	size_t len;
	int i;

	if (!ec_group || !pub_key) {
		goto end;
	}
	if (!kdf) {
		goto end;
	}

	/* init ciphertext_value */
	if (!(cv = OPENSSL_malloc(sizeof(SM2_CIPHERTEXT_VALUE)))) {
		goto end;
	}
	bzero(cv, sizeof(SM2_CIPHERTEXT_VALUE));
	cv->ephem_point = EC_POINT_new(ec_group);
	cv->ciphertext = OPENSSL_malloc(inlen);
	cv->ciphertext_size = inlen;
	if (!cv->ephem_point || !cv->ciphertext) {
		goto end;
	}

	point = EC_POINT_new(ec_group);
	n = BN_new();
	h = BN_new();
	k = BN_new();
	bn_ctx = BN_CTX_new();
	md_ctx = EVP_MD_CTX_create();
	if (!point || !n || !h || !k || !bn_ctx || !md_ctx) {
		goto end;
	}

	/* init ec domain parameters */
	if (!EC_GROUP_get_order(ec_group, n, bn_ctx)) {
		goto end;
	}
	if (!EC_GROUP_get_cofactor(ec_group, h, bn_ctx)) {
		goto end;
	}
	nbytes = (EC_GROUP_get_degree(ec_group) + 7) / 8;


	//OPENSSL_assert(nbytes == BN_num_bytes(n));

#if 0
	/* check sm2 curve and md is 256 bits */
	OPENSSL_assert(nbytes == 32);
	OPENSSL_assert(EVP_MD_size(kdf_md) == 32);
	OPENSSL_assert(EVP_MD_size(mac_md) == 32);
#endif

	do
	{
		/* A1: rand k in [1, n-1] */
		do {
			BN_rand_range(k, n);
		} while (BN_is_zero(k));

	
		/* A2: C1 = [k]G = (x1, y1) */
		if (!EC_POINT_mul(ec_group, cv->ephem_point, k, NULL, NULL, bn_ctx)) {
			goto end;
		}
		
		/* A3: check [h]P_B != O */
		if (!EC_POINT_mul(ec_group, point, NULL, pub_key, h, bn_ctx)) {
			goto end;
		}
		if (EC_POINT_is_at_infinity(ec_group, point)) {
			goto end;
		}

		/* A4: compute ECDH [k]P_B = (x2, y2) */
		if (!EC_POINT_mul(ec_group, point, NULL, pub_key, k, bn_ctx)) {
			goto end;
		}
		if (!(len = EC_POINT_point2oct(ec_group, point,
			POINT_CONVERSION_UNCOMPRESSED, buf, sizeof(buf), bn_ctx))) {
			goto end;
		}
		OPENSSL_assert(len == nbytes * 2 + 1);
		
		/* A5: t = KDF(x2 || y2, klen) */
		kdf(buf + 1, len - 1, cv->ciphertext, &cv->ciphertext_size);

		for (i = 0; i < cv->ciphertext_size; i++) {
			if (cv->ciphertext[i]) {
				break;
			}
		}
		if (i == cv->ciphertext_size) {
			continue;
		}

		break;

	} while (1);


	/* A6: C2 = M xor t */
	for (i = 0; i < inlen; i++) {
		cv->ciphertext[i] ^= in[i];
	}
	
	/* A7: C3 = Hash(x2 || M || y2) */
	if (!EVP_DigestInit_ex(md_ctx, mac_md, NULL)) {
		goto end;
	}
	if (!EVP_DigestUpdate(md_ctx, buf + 1, nbytes)) {
		goto end;
	}
	if (!EVP_DigestUpdate(md_ctx, in, inlen)) {
		goto end;
	}
	if (!EVP_DigestUpdate(md_ctx, buf + 1 + nbytes, nbytes)) {
		goto end;
	}
	if (!EVP_DigestFinal_ex(md_ctx, cv->mactag, &cv->mactag_size)) {
		goto end;
	}


	ok = 1;

end:
	if (!ok && cv) {
		SM2_CIPHERTEXT_VALUE_free(cv);
		cv = NULL;
	}

	if (point) EC_POINT_free(point);
	if (n) BN_free(n);
	if (h) BN_free(h);
	if (k) BN_free(k);
	if (bn_ctx) BN_CTX_free(bn_ctx);
	if (md_ctx) EVP_MD_CTX_destroy(md_ctx);

	return cv;
}
Exemplo n.º 6
0
int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
                 const EVP_MD *md, ENGINE *impl)
{
    int i, j, reset = 0;
    unsigned char pad[HMAC_MAX_MD_CBLOCK];

    /* If we are changing MD then we must have a key */
    if (md != NULL && md != ctx->md && (key == NULL || len < 0))
        return 0;

    if (md != NULL) {
        reset = 1;
        ctx->md = md;
    } else if (ctx->md) {
        md = ctx->md;
    } else {
        return 0;
    }

    if (key != NULL) {
        reset = 1;
        j = EVP_MD_block_size(md);
        OPENSSL_assert(j <= (int)sizeof(ctx->key));
        if (j < len) {
            if (!EVP_DigestInit_ex(ctx->md_ctx, md, impl))
                goto err;
            if (!EVP_DigestUpdate(ctx->md_ctx, key, len))
                goto err;
            if (!EVP_DigestFinal_ex(ctx->md_ctx, ctx->key,
                                    &ctx->key_length))
                goto err;
        } else {
            if (len < 0 || len > (int)sizeof(ctx->key))
                return 0;
            memcpy(ctx->key, key, len);
            ctx->key_length = len;
        }
        if (ctx->key_length != HMAC_MAX_MD_CBLOCK)
            memset(&ctx->key[ctx->key_length], 0,
                   HMAC_MAX_MD_CBLOCK - ctx->key_length);
    }

    if (reset) {
        for (i = 0; i < HMAC_MAX_MD_CBLOCK; i++)
            pad[i] = 0x36 ^ ctx->key[i];
        if (!EVP_DigestInit_ex(ctx->i_ctx, md, impl))
            goto err;
        if (!EVP_DigestUpdate(ctx->i_ctx, pad, EVP_MD_block_size(md)))
            goto err;

        for (i = 0; i < HMAC_MAX_MD_CBLOCK; i++)
            pad[i] = 0x5c ^ ctx->key[i];
        if (!EVP_DigestInit_ex(ctx->o_ctx, md, impl))
            goto err;
        if (!EVP_DigestUpdate(ctx->o_ctx, pad, EVP_MD_block_size(md)))
            goto err;
    }
    if (!EVP_MD_CTX_copy_ex(ctx->md_ctx, ctx->i_ctx))
        goto err;
    return 1;
err:
    return 0;
}
Exemplo n.º 7
0
/*******************************************************************-o-******
 * generate_Ku
 *
 * Parameters:
 *	*hashtype	MIB OID for the transform type for hashing.
 *	 hashtype_len	Length of OID value.
 *	*P		Pre-allocated bytes of passpharase.
 *	 pplen		Length of passphrase.
 *	*Ku		Buffer to contain Ku.
 *	*kulen		Length of Ku buffer.
 *      
 * Returns:
 *	SNMPERR_SUCCESS			Success.
 *	SNMPERR_GENERR			All errors.
 *
 *
 * Convert a passphrase into a master user key, Ku, according to the
 * algorithm given in RFC 2274 concerning the SNMPv3 User Security Model (USM)
 * as follows:
 *
 * Expand the passphrase to fill the passphrase buffer space, if necessary,
 * concatenation as many duplicates as possible of P to itself.  If P is
 * larger than the buffer space, truncate it to fit.
 *
 * Then hash the result with the given hashtype transform.  Return
 * the result as Ku.
 *
 * If successful, kulen contains the size of the hash written to Ku.
 *
 * NOTE  Passphrases less than USM_LENGTH_P_MIN characters in length
 *	 cause an error to be returned.
 *	 (Punt this check to the cmdline apps?  XXX)
 */
int
generate_Ku(	oid	*hashtype,	u_int  hashtype_len,
		u_char	*P,		size_t  pplen,
		u_char	*Ku,		size_t *kulen)
#if defined(USE_INTERNAL_MD5) || defined(USE_OPENSSL)
{
	int		 rval   = SNMPERR_SUCCESS,
			 nbytes = USM_LENGTH_EXPANDED_PASSPHRASE;

        u_int            i, pindex = 0;

	u_char		 buf[USM_LENGTH_KU_HASHBLOCK],
			*bufp;

#ifdef USE_OPENSSL
	EVP_MD_CTX      *ctx = malloc(sizeof(EVP_MD_CTX));
#else
        MDstruct         MD;
#endif
	/*
	 * Sanity check.
	 */
	if ( !hashtype || !P || !Ku || !kulen
		|| (*kulen<=0)
		|| (hashtype_len != USM_LENGTH_OID_TRANSFORM) )
	{
		QUITFUN(SNMPERR_GENERR, generate_Ku_quit);
	}

        if (pplen < USM_LENGTH_P_MIN) {
#ifdef SNMP_TESTING_CODE
          snmp_log(LOG_WARNING, "Warning: passphrase chosen is below the length requiremnts of the USM.\n");
#else
          snmp_set_detail("Password length too short.");
          QUITFUN(SNMPERR_GENERR, generate_Ku_quit);
#endif
        }


	/*
	 * Setup for the transform type.
	 */
#ifdef USE_OPENSSL
	
	if (ISTRANSFORM(hashtype, HMACMD5Auth))
	  EVP_DigestInit(ctx, EVP_md5());
	else if (ISTRANSFORM(hashtype, HMACSHA1Auth))
	  EVP_DigestInit(ctx, EVP_sha1());
	else  {
	  free(ctx);
	  return (SNMPERR_GENERR);
	}
#else 
        MDbegin(&MD);
#endif /* USE_OPENSSL */

        while (nbytes > 0) {
                bufp = buf;
                for (i = 0; i < USM_LENGTH_KU_HASHBLOCK; i++) {
                        *bufp++ = P[pindex++ % pplen];
                }
#ifdef USE_OPENSSL
		EVP_DigestUpdate(ctx, buf, USM_LENGTH_KU_HASHBLOCK);
#else
                if (MDupdate(&MD, buf, USM_LENGTH_KU_HASHBLOCK*8)) {
                    rval = SNMPERR_USM_ENCRYPTIONERROR;
                    goto md5_fin;
                }
#endif /* USE_OPENSSL */

                nbytes -= USM_LENGTH_KU_HASHBLOCK;
        }

#ifdef USE_OPENSSL
	EVP_DigestFinal(ctx, (unsigned char *) Ku, (unsigned int *) kulen);
	/* what about free() */
#else
        if (MDupdate(&MD, buf, 0)) {
            rval = SNMPERR_USM_ENCRYPTIONERROR;
            goto md5_fin;
        }
        *kulen = sc_get_properlength(hashtype, hashtype_len);
        MDget(&MD, Ku, *kulen);
md5_fin:
        memset(&MD, 0, sizeof(MD));
#endif /* USE_OPENSSL */


#ifdef SNMP_TESTING_CODE
        DEBUGMSGTL(("generate_Ku", "generating Ku (from %s): ", P));
        for(i=0; i < *kulen; i++)
          DEBUGMSG(("generate_Ku", "%02x",Ku[i]));
        DEBUGMSG(("generate_Ku","\n"));
#endif /* SNMP_TESTING_CODE */


generate_Ku_quit:
	memset(buf, 0, sizeof(buf));
#ifdef USE_OPENSSL
	free(ctx);
#endif
	return rval;

}  /* end generate_Ku() */
Exemplo n.º 8
0
int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt,
                       int saltlen, int id, int iter, int n,
                       unsigned char *out, const EVP_MD *md_type)
{
    unsigned char *B = NULL, *D = NULL, *I = NULL, *p = NULL, *Ai = NULL;
    int Slen, Plen, Ilen, Ijlen;
    int i, j, u, v;
    int ret = 0;
    BIGNUM *Ij = NULL, *Bpl1 = NULL; /* These hold Ij and B + 1 */
    EVP_MD_CTX *ctx = NULL;
#ifdef  DEBUG_KEYGEN
    unsigned char *tmpout = out;
    int tmpn = n;
#endif

    ctx = EVP_MD_CTX_new();
    if (ctx == NULL)
        goto err;

#ifdef  DEBUG_KEYGEN
    fprintf(stderr, "KEYGEN DEBUG\n");
    fprintf(stderr, "ID %d, ITER %d\n", id, iter);
    fprintf(stderr, "Password (length %d):\n", passlen);
    h__dump(pass, passlen);
    fprintf(stderr, "Salt (length %d):\n", saltlen);
    h__dump(salt, saltlen);
#endif
    v = EVP_MD_block_size(md_type);
    u = EVP_MD_size(md_type);
    if (u < 0)
        return 0;
    D = OPENSSL_malloc(v);
    Ai = OPENSSL_malloc(u);
    B = OPENSSL_malloc(v + 1);
    Slen = v * ((saltlen + v - 1) / v);
    if (passlen)
        Plen = v * ((passlen + v - 1) / v);
    else
        Plen = 0;
    Ilen = Slen + Plen;
    I = OPENSSL_malloc(Ilen);
    Ij = BN_new();
    Bpl1 = BN_new();
    if (D == NULL || Ai == NULL || B == NULL || I == NULL || Ij == NULL
            || Bpl1 == NULL)
        goto err;
    for (i = 0; i < v; i++)
        D[i] = id;
    p = I;
    for (i = 0; i < Slen; i++)
        *p++ = salt[i % saltlen];
    for (i = 0; i < Plen; i++)
        *p++ = pass[i % passlen];
    for (;;) {
        if (!EVP_DigestInit_ex(ctx, md_type, NULL)
            || !EVP_DigestUpdate(ctx, D, v)
            || !EVP_DigestUpdate(ctx, I, Ilen)
            || !EVP_DigestFinal_ex(ctx, Ai, NULL))
            goto err;
        for (j = 1; j < iter; j++) {
            if (!EVP_DigestInit_ex(ctx, md_type, NULL)
                || !EVP_DigestUpdate(ctx, Ai, u)
                || !EVP_DigestFinal_ex(ctx, Ai, NULL))
                goto err;
        }
        memcpy(out, Ai, min(n, u));
        if (u >= n) {
#ifdef DEBUG_KEYGEN
            fprintf(stderr, "Output KEY (length %d)\n", tmpn);
            h__dump(tmpout, tmpn);
#endif
            ret = 1;
            goto end;
        }
        n -= u;
        out += u;
        for (j = 0; j < v; j++)
            B[j] = Ai[j % u];
        /* Work out B + 1 first then can use B as tmp space */
        if (!BN_bin2bn(B, v, Bpl1))
            goto err;
        if (!BN_add_word(Bpl1, 1))
            goto err;
        for (j = 0; j < Ilen; j += v) {
            if (!BN_bin2bn(I + j, v, Ij))
                goto err;
            if (!BN_add(Ij, Ij, Bpl1))
                goto err;
            if (!BN_bn2bin(Ij, B))
                goto err;
            Ijlen = BN_num_bytes(Ij);
            /* If more than 2^(v*8) - 1 cut off MSB */
            if (Ijlen > v) {
                if (!BN_bn2bin(Ij, B))
                    goto err;
                memcpy(I + j, B + 1, v);
#ifndef PKCS12_BROKEN_KEYGEN
                /* If less than v bytes pad with zeroes */
            } else if (Ijlen < v) {
                memset(I + j, 0, v - Ijlen);
                if (!BN_bn2bin(Ij, I + j + v - Ijlen))
                    goto err;
#endif
            } else if (!BN_bn2bin(Ij, I + j))
                goto err;
        }
    }

 err:
    PKCS12err(PKCS12_F_PKCS12_KEY_GEN_UNI, ERR_R_MALLOC_FAILURE);

 end:
    OPENSSL_free(Ai);
    OPENSSL_free(B);
    OPENSSL_free(D);
    OPENSSL_free(I);
    BN_free(Ij);
    BN_free(Bpl1);
    EVP_MD_CTX_free(ctx);
    return ret;
}
Exemplo n.º 9
0
int EVP_tls_cbc_digest_record(const EVP_MD *md, uint8_t *md_out,
                              size_t *md_out_size, const uint8_t header[13],
                              const uint8_t *data, size_t data_plus_mac_size,
                              size_t data_plus_mac_plus_padding_size,
                              const uint8_t *mac_secret,
                              unsigned mac_secret_length) {
  union {
    double align;
    uint8_t c[sizeof(LARGEST_DIGEST_CTX)];
  } md_state;
  void (*md_final_raw)(void *ctx, uint8_t *md_out);
  void (*md_transform)(void *ctx, const uint8_t *block);
  unsigned md_size, md_block_size = 64;
  unsigned len, max_mac_bytes, num_blocks, num_starting_blocks, k,
           mac_end_offset, c, index_a, index_b;
  unsigned int bits; /* at most 18 bits */
  uint8_t length_bytes[MAX_HASH_BIT_COUNT_BYTES];
  /* hmac_pad is the masked HMAC key. */
  uint8_t hmac_pad[MAX_HASH_BLOCK_SIZE];
  uint8_t first_block[MAX_HASH_BLOCK_SIZE];
  uint8_t mac_out[EVP_MAX_MD_SIZE];
  unsigned i, j, md_out_size_u;
  EVP_MD_CTX md_ctx;
  /* mdLengthSize is the number of bytes in the length field that terminates
  * the hash. */
  unsigned md_length_size = 8;

  /* This is a, hopefully redundant, check that allows us to forget about
   * many possible overflows later in this function. */
  assert(data_plus_mac_plus_padding_size < 1024 * 1024);

  switch (EVP_MD_type(md)) {
    case NID_sha1:
      SHA1_Init((SHA_CTX *)md_state.c);
      md_final_raw = tls1_sha1_final_raw;
      md_transform =
          (void (*)(void *ctx, const uint8_t *block))SHA1_Transform;
      md_size = 20;
      break;

    case NID_sha256:
      SHA256_Init((SHA256_CTX *)md_state.c);
      md_final_raw = tls1_sha256_final_raw;
      md_transform =
          (void (*)(void *ctx, const uint8_t *block))SHA256_Transform;
      md_size = 32;
      break;

    case NID_sha384:
      SHA384_Init((SHA512_CTX *)md_state.c);
      md_final_raw = tls1_sha512_final_raw;
      md_transform =
          (void (*)(void *ctx, const uint8_t *block))SHA512_Transform;
      md_size = 384 / 8;
      md_block_size = 128;
      md_length_size = 16;
      break;

    default:
      /* EVP_tls_cbc_record_digest_supported should have been called first to
       * check that the hash function is supported. */
      assert(0);
      *md_out_size = 0;
      return 0;
  }

  assert(md_length_size <= MAX_HASH_BIT_COUNT_BYTES);
  assert(md_block_size <= MAX_HASH_BLOCK_SIZE);
  assert(md_size <= EVP_MAX_MD_SIZE);

  static const unsigned kHeaderLength = 13;

  /* kVarianceBlocks is the number of blocks of the hash that we have to
   * calculate in constant time because they could be altered by the
   * padding value.
   *
   * TLSv1 has MACs up to 48 bytes long (SHA-384) and the padding is not
   * required to be minimal. Therefore we say that the final six blocks
   * can vary based on the padding. */
  static const unsigned kVarianceBlocks = 6;

  /* From now on we're dealing with the MAC, which conceptually has 13
   * bytes of `header' before the start of the data. */
  len = data_plus_mac_plus_padding_size + kHeaderLength;
  /* max_mac_bytes contains the maximum bytes of bytes in the MAC, including
  * |header|, assuming that there's no padding. */
  max_mac_bytes = len - md_size - 1;
  /* num_blocks is the maximum number of hash blocks. */
  num_blocks =
      (max_mac_bytes + 1 + md_length_size + md_block_size - 1) / md_block_size;
  /* In order to calculate the MAC in constant time we have to handle
   * the final blocks specially because the padding value could cause the
   * end to appear somewhere in the final |kVarianceBlocks| blocks and we
   * can't leak where. However, |num_starting_blocks| worth of data can
   * be hashed right away because no padding value can affect whether
   * they are plaintext. */
  num_starting_blocks = 0;
  /* k is the starting byte offset into the conceptual header||data where
   * we start processing. */
  k = 0;
  /* mac_end_offset is the index just past the end of the data to be
   * MACed. */
  mac_end_offset = data_plus_mac_size + kHeaderLength - md_size;
  /* c is the index of the 0x80 byte in the final hash block that
   * contains application data. */
  c = mac_end_offset % md_block_size;
  /* index_a is the hash block number that contains the 0x80 terminating
   * value. */
  index_a = mac_end_offset / md_block_size;
  /* index_b is the hash block number that contains the 64-bit hash
   * length, in bits. */
  index_b = (mac_end_offset + md_length_size) / md_block_size;
  /* bits is the hash-length in bits. It includes the additional hash
   * block for the masked HMAC key. */

  if (num_blocks > kVarianceBlocks) {
    num_starting_blocks = num_blocks - kVarianceBlocks;
    k = md_block_size * num_starting_blocks;
  }

  bits = 8 * mac_end_offset;

  /* Compute the initial HMAC block. */
  bits += 8 * md_block_size;
  memset(hmac_pad, 0, md_block_size);
  assert(mac_secret_length <= sizeof(hmac_pad));
  memcpy(hmac_pad, mac_secret, mac_secret_length);
  for (i = 0; i < md_block_size; i++) {
    hmac_pad[i] ^= 0x36;
  }

  md_transform(md_state.c, hmac_pad);

  memset(length_bytes, 0, md_length_size - 4);
  length_bytes[md_length_size - 4] = (uint8_t)(bits >> 24);
  length_bytes[md_length_size - 3] = (uint8_t)(bits >> 16);
  length_bytes[md_length_size - 2] = (uint8_t)(bits >> 8);
  length_bytes[md_length_size - 1] = (uint8_t)bits;

  if (k > 0) {
    /* k is a multiple of md_block_size. */
    memcpy(first_block, header, 13);
    memcpy(first_block + 13, data, md_block_size - 13);
    md_transform(md_state.c, first_block);
    for (i = 1; i < k / md_block_size; i++) {
      md_transform(md_state.c, data + md_block_size * i - 13);
    }
  }

  memset(mac_out, 0, sizeof(mac_out));

  /* We now process the final hash blocks. For each block, we construct
   * it in constant time. If the |i==index_a| then we'll include the 0x80
   * bytes and zero pad etc. For each block we selectively copy it, in
   * constant time, to |mac_out|. */
  for (i = num_starting_blocks; i <= num_starting_blocks + kVarianceBlocks;
       i++) {
    uint8_t block[MAX_HASH_BLOCK_SIZE];
    uint8_t is_block_a = constant_time_eq_8(i, index_a);
    uint8_t is_block_b = constant_time_eq_8(i, index_b);
    for (j = 0; j < md_block_size; j++) {
      uint8_t b = 0, is_past_c, is_past_cp1;
      if (k < kHeaderLength) {
        b = header[k];
      } else if (k < data_plus_mac_plus_padding_size + kHeaderLength) {
        b = data[k - kHeaderLength];
      }
      k++;

      is_past_c = is_block_a & constant_time_ge_8(j, c);
      is_past_cp1 = is_block_a & constant_time_ge_8(j, c + 1);
      /* If this is the block containing the end of the
       * application data, and we are at the offset for the
       * 0x80 value, then overwrite b with 0x80. */
      b = constant_time_select_8(is_past_c, 0x80, b);
      /* If this the the block containing the end of the
       * application data and we're past the 0x80 value then
       * just write zero. */
      b = b & ~is_past_cp1;
      /* If this is index_b (the final block), but not
       * index_a (the end of the data), then the 64-bit
       * length didn't fit into index_a and we're having to
       * add an extra block of zeros. */
      b &= ~is_block_b | is_block_a;

      /* The final bytes of one of the blocks contains the
       * length. */
      if (j >= md_block_size - md_length_size) {
        /* If this is index_b, write a length byte. */
        b = constant_time_select_8(
            is_block_b, length_bytes[j - (md_block_size - md_length_size)], b);
      }
      block[j] = b;
    }

    md_transform(md_state.c, block);
    md_final_raw(md_state.c, block);
    /* If this is index_b, copy the hash value to |mac_out|. */
    for (j = 0; j < md_size; j++) {
      mac_out[j] |= block[j] & is_block_b;
    }
  }

  EVP_MD_CTX_init(&md_ctx);
  if (!EVP_DigestInit_ex(&md_ctx, md, NULL /* engine */)) {
    EVP_MD_CTX_cleanup(&md_ctx);
    return 0;
  }

  /* Complete the HMAC in the standard manner. */
  for (i = 0; i < md_block_size; i++) {
    hmac_pad[i] ^= 0x6a;
  }

  EVP_DigestUpdate(&md_ctx, hmac_pad, md_block_size);
  EVP_DigestUpdate(&md_ctx, mac_out, md_size);
  EVP_DigestFinal(&md_ctx, md_out, &md_out_size_u);
  *md_out_size = md_out_size_u;
  EVP_MD_CTX_cleanup(&md_ctx);

  return 1;
}
Exemplo n.º 10
0
krb5_error_code
_krb5_pk_octetstring2key(krb5_context context,
			 krb5_enctype type,
			 const void *dhdata,
			 size_t dhsize,
			 const heim_octet_string *c_n,
			 const heim_octet_string *k_n,
			 krb5_keyblock *key)
{
    struct _krb5_encryption_type *et = _krb5_find_enctype(type);
    krb5_error_code ret;
    size_t keylen, offset;
    void *keydata;
    unsigned char counter;
    unsigned char shaoutput[SHA_DIGEST_LENGTH];
    EVP_MD_CTX *m;

    if(et == NULL) {
	krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP,
			       N_("encryption type %d not supported", ""),
			       type);
	return KRB5_PROG_ETYPE_NOSUPP;
    }
    keylen = (et->keytype->bits + 7) / 8;

    keydata = malloc(keylen);
    if (keydata == NULL) {
	krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
	return ENOMEM;
    }

    m = EVP_MD_CTX_create();
    if (m == NULL) {
	free(keydata);
	krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
	return ENOMEM;
    }

    counter = 0;
    offset = 0;
    do {

	EVP_DigestInit_ex(m, EVP_sha1(), NULL);
	EVP_DigestUpdate(m, &counter, 1);
	EVP_DigestUpdate(m, dhdata, dhsize);

	if (c_n)
	    EVP_DigestUpdate(m, c_n->data, c_n->length);
	if (k_n)
	    EVP_DigestUpdate(m, k_n->data, k_n->length);

	EVP_DigestFinal_ex(m, shaoutput, NULL);

	memcpy((unsigned char *)keydata + offset,
	       shaoutput,
	       min(keylen - offset, sizeof(shaoutput)));

	offset += sizeof(shaoutput);
	counter++;
    } while(offset < keylen);
    memset(shaoutput, 0, sizeof(shaoutput));

    EVP_MD_CTX_destroy(m);

    ret = krb5_random_to_key(context, type, keydata, keylen, key);
    memset(keydata, 0, sizeof(keylen));
    free(keydata);
    return ret;
}
Exemplo n.º 11
0
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);
}
Exemplo n.º 12
0
krb5_error_code
_krb5_pk_kdf(krb5_context context,
	     const struct AlgorithmIdentifier *ai,
	     const void *dhdata,
	     size_t dhsize,
	     krb5_const_principal client,
	     krb5_const_principal server,
	     krb5_enctype enctype,
	     const krb5_data *as_req,
	     const krb5_data *pk_as_rep,
	     const Ticket *ticket,
	     krb5_keyblock *key)
{
    struct _krb5_encryption_type *et;
    krb5_error_code ret;
    krb5_data other;
    size_t keylen, offset;
    uint32_t counter;
    unsigned char *keydata;
    unsigned char shaoutput[SHA512_DIGEST_LENGTH];
    const EVP_MD *md;
    EVP_MD_CTX *m;

    if (der_heim_oid_cmp(&asn1_oid_id_pkinit_kdf_ah_sha1, &ai->algorithm) == 0) {
        md = EVP_sha1();
    } else if (der_heim_oid_cmp(&asn1_oid_id_pkinit_kdf_ah_sha256, &ai->algorithm) == 0) {
        md = EVP_sha256();
    } else if (der_heim_oid_cmp(&asn1_oid_id_pkinit_kdf_ah_sha512, &ai->algorithm) == 0) {
        md = EVP_sha512();
    } else {
	krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP,
			       N_("KDF not supported", ""));
	return KRB5_PROG_ETYPE_NOSUPP;
    }
    if (ai->parameters != NULL &&
	(ai->parameters->length != 2 ||
	 memcmp(ai->parameters->data, "\x05\x00", 2) != 0))
	{
	    krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP,
				   N_("kdf params not NULL or the NULL-type",
				      ""));
	    return KRB5_PROG_ETYPE_NOSUPP;
	}

    et = _krb5_find_enctype(enctype);
    if(et == NULL) {
	krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP,
			       N_("encryption type %d not supported", ""),
			       enctype);
	return KRB5_PROG_ETYPE_NOSUPP;
    }
    keylen = (et->keytype->bits + 7) / 8;

    keydata = malloc(keylen);
    if (keydata == NULL) {
	krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
	return ENOMEM;
    }

    ret = encode_otherinfo(context, ai, client, server,
			   enctype, as_req, pk_as_rep, ticket, &other);
    if (ret) {
	free(keydata);
	return ret;
    }

    m = EVP_MD_CTX_create();
    if (m == NULL) {
	free(keydata);
	free(other.data);
	krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
	return ENOMEM;
    }

    offset = 0;
    counter = 1;
    do {
	unsigned char cdata[4];

	EVP_DigestInit_ex(m, md, NULL);
	_krb5_put_int(cdata, counter, 4);
	EVP_DigestUpdate(m, cdata, 4);
	EVP_DigestUpdate(m, dhdata, dhsize);
	EVP_DigestUpdate(m, other.data, other.length);

	EVP_DigestFinal_ex(m, shaoutput, NULL);

	memcpy((unsigned char *)keydata + offset,
	       shaoutput,
	       min(keylen - offset, EVP_MD_CTX_size(m)));

	offset += EVP_MD_CTX_size(m);
	counter++;
    } while(offset < keylen);
    memset(shaoutput, 0, sizeof(shaoutput));

    EVP_MD_CTX_destroy(m);
    free(other.data);

    ret = krb5_random_to_key(context, enctype, keydata, keylen, key);
    memset(keydata, 0, sizeof(keylen));
    free(keydata);

    return ret;
}
Exemplo n.º 13
0
static isc_result_t
opensslrsa_adddata(dst_context_t *dctx, const isc_region_t *data) {
#if USE_EVP
	EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
#endif

#ifndef PK11_MD5_DISABLE
	REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 ||
		dctx->key->key_alg == DST_ALG_RSASHA1 ||
		dctx->key->key_alg == DST_ALG_NSEC3RSASHA1 ||
		dctx->key->key_alg == DST_ALG_RSASHA256 ||
		dctx->key->key_alg == DST_ALG_RSASHA512);
#else
	REQUIRE(dctx->key->key_alg == DST_ALG_RSASHA1 ||
		dctx->key->key_alg == DST_ALG_NSEC3RSASHA1 ||
		dctx->key->key_alg == DST_ALG_RSASHA256 ||
		dctx->key->key_alg == DST_ALG_RSASHA512);
#endif

#if USE_EVP
	if (!EVP_DigestUpdate(evp_md_ctx, data->base, data->length)) {
		return (dst__openssl_toresult3(dctx->category,
					       "EVP_DigestUpdate",
					       ISC_R_FAILURE));
	}
#else
	switch (dctx->key->key_alg) {
#ifndef PK11_MD5_DISABLE
	case DST_ALG_RSAMD5:
		{
			isc_md5_t *md5ctx = dctx->ctxdata.md5ctx;

			isc_md5_update(md5ctx, data->base, data->length);
		}
		break;
#endif
	case DST_ALG_RSASHA1:
	case DST_ALG_NSEC3RSASHA1:
		{
			isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;

			isc_sha1_update(sha1ctx, data->base, data->length);
		}
		break;
	case DST_ALG_RSASHA256:
		{
			isc_sha256_t *sha256ctx = dctx->ctxdata.sha256ctx;

			isc_sha256_update(sha256ctx, data->base, data->length);
		}
		break;
	case DST_ALG_RSASHA512:
		{
			isc_sha512_t *sha512ctx = dctx->ctxdata.sha512ctx;

			isc_sha512_update(sha512ctx, data->base, data->length);
		}
		break;
	default:
		INSIST(0);
	}
#endif
	return (ISC_R_SUCCESS);
}
Exemplo n.º 14
0
int
ssh_dss_verify(ncrack_ssh_state *nstate, const Key *key,
    const u_char *signature, u_int signaturelen,
    const u_char *data, u_int datalen)
{
	DSA_SIG *sig;
	const EVP_MD *evp_md = EVP_sha1();
	EVP_MD_CTX md;
	u_char digest[EVP_MAX_MD_SIZE], *sigblob;
	u_int len, dlen;
	int rlen, ret;
	Buffer b;

	if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) {
		ssherror("ssh_dss_verify: no DSA key");
		return -1;
	}

	/* fetch signature */
	if (nstate->datafellows & SSH_BUG_SIGBLOB) {
		sigblob = xmalloc(signaturelen);
		memcpy(sigblob, signature, signaturelen);
		len = signaturelen;
	} else {
		/* ietf-drafts */
		char *ktype;
		buffer_init(&b);
		buffer_append(&b, signature, signaturelen);
		ktype = buffer_get_string(&b, NULL);
		if (strcmp("ssh-dss", ktype) != 0) {
			ssherror("ssh_dss_verify: cannot handle type %s", ktype);
			buffer_free(&b);
			xfree(ktype);
			return -1;
		}
		xfree(ktype);
		sigblob = buffer_get_string(&b, &len);
		rlen = buffer_len(&b);
		buffer_free(&b);
		if (rlen != 0) {
			ssherror("ssh_dss_verify: "
			    "remaining bytes in signature %d", rlen);
			xfree(sigblob);
			return -1;
		}
	}

	if (len != SIGBLOB_LEN) {
		fatal("bad sigbloblen %u != SIGBLOB_LEN", len);
	}

	/* parse signature */
	if ((sig = DSA_SIG_new()) == NULL)
		fatal("ssh_dss_verify: DSA_SIG_new failed");
	if ((sig->r = BN_new()) == NULL)
		fatal("ssh_dss_verify: BN_new failed");
	if ((sig->s = BN_new()) == NULL)
		fatal("ssh_dss_verify: BN_new failed");
	if ((BN_bin2bn(sigblob, INTBLOB_LEN, sig->r) == NULL) ||
	    (BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s) == NULL))
		fatal("ssh_dss_verify: BN_bin2bn failed");

	/* clean up */
	memset(sigblob, 0, len);
	xfree(sigblob);

	/* sha1 the data */
	EVP_DigestInit(&md, evp_md);
	EVP_DigestUpdate(&md, data, datalen);
	EVP_DigestFinal(&md, digest, &dlen);

	ret = DSA_do_verify(digest, dlen, sig, key->dsa);
	memset(digest, 'd', sizeof(digest));

	DSA_SIG_free(sig);

	debug("ssh_dss_verify: signature %s",
	    ret == 1 ? "correct" : ret == 0 ? "incorrect" : "error");
	return ret;
}
Exemplo n.º 15
0
bool RarVolume::DecryptRar3Prepare(const uint8 salt[8])
{
	WString wstr(*m_password);
	int len = wstr.Length();
	if (len == 0) return false;

	CharBuffer seed(len * 2 + 8);
	for (int i = 0; i < len; i++)
	{
		wchar_t ch = wstr[i];
		seed[i * 2] = ch & 0xFF;
		seed[i * 2 + 1] = (ch & 0xFF00) >> 8;
	}
	memcpy(seed + len * 2, salt, 8);

	debug("seed: %s", *Util::FormatBuffer((const char*)seed, seed.Size()));

#ifdef HAVE_OPENSSL
	EVP_MD_CTX* context = EVP_MD_CTX_create();

	if (!EVP_DigestInit(context, EVP_sha1()))
	{
		EVP_MD_CTX_destroy(context);
		return false;
	}
#elif defined(HAVE_NETTLE)
	sha1_ctx context;
	sha1_init(&context);
#else
	return false;
#endif

	uint8 digest[20];
	const int rounds = 0x40000;

	for (int i = 0; i < rounds; i++)
	{
#ifdef HAVE_OPENSSL
		EVP_DigestUpdate(context, *seed, seed.Size());
#elif defined(HAVE_NETTLE)
		sha1_update(&context, seed.Size(), (const uint8_t*)*seed);
#endif

		uint8 buf[3];
		buf[0] = (uint8)i;
		buf[1] = (uint8)(i >> 8);
		buf[2] = (uint8)(i >> 16);

#ifdef HAVE_OPENSSL
		EVP_DigestUpdate(context, buf, sizeof(buf));
#elif defined(HAVE_NETTLE)
		sha1_update(&context, sizeof(buf), buf);
#endif

		if (i % (rounds / 16) == 0)
		{
#ifdef HAVE_OPENSSL
			EVP_MD_CTX* ivContext = EVP_MD_CTX_create();
			EVP_MD_CTX_copy(ivContext, context);
			EVP_DigestFinal(ivContext, digest, nullptr);
			EVP_MD_CTX_destroy(ivContext);
#elif defined(HAVE_NETTLE)
			sha1_ctx ivContext = context;
			sha1_digest(&ivContext, sizeof(digest), digest);
#endif
			m_decryptIV[i / (rounds / 16)] = digest[sizeof(digest) - 1];
		}
	}

#ifdef HAVE_OPENSSL
	EVP_DigestFinal(context, digest, nullptr);
	EVP_MD_CTX_destroy(context);
#elif defined(HAVE_NETTLE)
	sha1_digest(&context, sizeof(digest), digest);
#endif

	debug("digest: %s", *Util::FormatBuffer((const char*)digest, sizeof(digest)));

	for (int i = 0; i < 4; i++)
	{
		for (int j = 0; j < 4; j++)
		{
			m_decryptKey[i * 4 + j] = digest[i * 4 + 3 - j];
		}
	}

	debug("key: %s", *Util::FormatBuffer((const char*)m_decryptKey, sizeof(m_decryptKey)));
	debug("iv: %s", *Util::FormatBuffer((const char*)m_decryptIV, sizeof(m_decryptIV)));

	return true;
}
Exemplo n.º 16
0
int GTDataHash_create(int hash_algorithm,
		const unsigned char* data, size_t data_length, GTDataHash **data_hash)
{
	int res = GT_UNKNOWN_ERROR;
	EVP_MD_CTX md_ctx;
	const EVP_MD *evp_md;
	GTDataHash *tmp_data_hash = NULL;
	unsigned char* tmp_hash = NULL;
	size_t tmp_length;
	unsigned int digest_length;

	if ((data == NULL && data_length != 0) || data_hash == NULL) {
		res = GT_INVALID_ARGUMENT;
		goto cleanup;
	}

	if (!GT_isSupportedHashAlgorithm(hash_algorithm)) {
		res = GT_UNTRUSTED_HASH_ALGORITHM;
		goto cleanup;
	}

	evp_md = GT_hashChainIDToEVP(hash_algorithm);
	if (evp_md == NULL) {
		res = GT_OUT_OF_MEMORY;
		goto cleanup;
	}

	tmp_data_hash = GT_malloc(sizeof(GTDataHash));
	if (tmp_data_hash == NULL) {
		res = GT_OUT_OF_MEMORY;
		goto cleanup;
	}
	tmp_data_hash->digest = NULL;
	tmp_data_hash->context = NULL;

	tmp_length = EVP_MD_size(evp_md);
	tmp_hash = GT_malloc(tmp_length);
	if (tmp_hash == NULL) {
		res = GT_OUT_OF_MEMORY;
		goto cleanup;
	}

	EVP_DigestInit(&md_ctx, evp_md);
	EVP_DigestUpdate(&md_ctx, data, data_length);
	EVP_DigestFinal(&md_ctx, tmp_hash, &digest_length);
	assert(digest_length == tmp_length);

	tmp_data_hash->digest = tmp_hash;
	tmp_hash = NULL;
	tmp_data_hash->digest_length = tmp_length;
	tmp_data_hash->algorithm = hash_algorithm;
	*data_hash = tmp_data_hash;
	tmp_data_hash = NULL;

	res = GT_OK;

cleanup:
	GT_free(tmp_hash);
	GTDataHash_free(tmp_data_hash);

	return res;
}
Exemplo n.º 17
0
int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len)
{
    if (!ctx->md)
        return 0;
    return EVP_DigestUpdate(ctx->md_ctx, data, len);
}
Exemplo n.º 18
0
int PEM_SignUpdate(EVP_MD_CTX *ctx, unsigned char *data, unsigned int count)
{
    return EVP_DigestUpdate(ctx, data, count);
}
Exemplo n.º 19
0
 void write_impl(const char* ptr, size_t size) override { EVP_DigestUpdate(md_ctx, ptr, size); }
Exemplo n.º 20
0
int ssl3_change_cipher_state(SSL *s, int which)
	{
	unsigned char *p,*key_block,*mac_secret;
	unsigned char exp_key[EVP_MAX_KEY_LENGTH];
	unsigned char exp_iv[EVP_MAX_IV_LENGTH];
	unsigned char *ms,*key,*iv,*er1,*er2;
	EVP_CIPHER_CTX *dd;
	const EVP_CIPHER *c;
#ifndef OPENSSL_NO_COMP
	COMP_METHOD *comp;
#endif
	const EVP_MD *m;
	EVP_MD_CTX md;
	int is_exp,n,i,j,k,cl;
	int reuse_dd = 0;

	is_exp=SSL_C_IS_EXPORT(s->s3->tmp.new_cipher);
	c=s->s3->tmp.new_sym_enc;
	m=s->s3->tmp.new_hash;
#ifndef OPENSSL_NO_COMP
	if (s->s3->tmp.new_compression == NULL)
		comp=NULL;
	else
		comp=s->s3->tmp.new_compression->method;
#endif
	key_block=s->s3->tmp.key_block;

	if (which & SSL3_CC_READ)
		{
		if (s->enc_read_ctx != NULL)
			reuse_dd = 1;
		else if ((s->enc_read_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL)
			goto err;
		else
			/* make sure it's intialized in case we exit later with an error */
			EVP_CIPHER_CTX_init(s->enc_read_ctx);
		dd= s->enc_read_ctx;
		s->read_hash=m;
#ifndef OPENSSL_NO_COMP
		/* COMPRESS */
		if (s->expand != NULL)
			{
			COMP_CTX_free(s->expand);
			s->expand=NULL;
			}
		if (comp != NULL)
			{
			s->expand=COMP_CTX_new(comp);
			if (s->expand == NULL)
				{
				SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR);
				goto err2;
				}
			if (s->s3->rrec.comp == NULL)
				s->s3->rrec.comp=(unsigned char *)
					OPENSSL_malloc(SSL3_RT_MAX_PLAIN_LENGTH);
			if (s->s3->rrec.comp == NULL)
				goto err;
			}
#endif
		memset(&(s->s3->read_sequence[0]),0,8);
		mac_secret= &(s->s3->read_mac_secret[0]);
		}
	else
		{
		if (s->enc_write_ctx != NULL)
			reuse_dd = 1;
		else if ((s->enc_write_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL)
			goto err;
		else
			/* make sure it's intialized in case we exit later with an error */
			EVP_CIPHER_CTX_init(s->enc_write_ctx);
		dd= s->enc_write_ctx;
		s->write_hash=m;
#ifndef OPENSSL_NO_COMP
		/* COMPRESS */
		if (s->compress != NULL)
			{
			COMP_CTX_free(s->compress);
			s->compress=NULL;
			}
		if (comp != NULL)
			{
			s->compress=COMP_CTX_new(comp);
			if (s->compress == NULL)
				{
				SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR);
				goto err2;
				}
			}
#endif
		memset(&(s->s3->write_sequence[0]),0,8);
		mac_secret= &(s->s3->write_mac_secret[0]);
		}

	if (reuse_dd)
		EVP_CIPHER_CTX_cleanup(dd);

	p=s->s3->tmp.key_block;
	i=EVP_MD_size(m);
	cl=EVP_CIPHER_key_length(c);
	j=is_exp ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ?
		 cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl;
	/* Was j=(is_exp)?5:EVP_CIPHER_key_length(c); */
	k=EVP_CIPHER_iv_length(c);
	if (	(which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) ||
		(which == SSL3_CHANGE_CIPHER_SERVER_READ))
		{
		ms=  &(p[ 0]); n=i+i;
		key= &(p[ n]); n+=j+j;
		iv=  &(p[ n]); n+=k+k;
		er1= &(s->s3->client_random[0]);
		er2= &(s->s3->server_random[0]);
		}
	else
		{
		n=i;
		ms=  &(p[ n]); n+=i+j;
		key= &(p[ n]); n+=j+k;
		iv=  &(p[ n]); n+=k;
		er1= &(s->s3->server_random[0]);
		er2= &(s->s3->client_random[0]);
		}

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

	EVP_MD_CTX_init(&md);
	memcpy(mac_secret,ms,i);
	if (is_exp)
		{
		/* In here I set both the read and write key/iv to the
		 * same value since only the correct one will be used :-).
		 */
		EVP_DigestInit_ex(&md,EVP_md5(), NULL);
		EVP_DigestUpdate(&md,key,j);
		EVP_DigestUpdate(&md,er1,SSL3_RANDOM_SIZE);
		EVP_DigestUpdate(&md,er2,SSL3_RANDOM_SIZE);
		EVP_DigestFinal_ex(&md,&(exp_key[0]),NULL);
		key= &(exp_key[0]);

		if (k > 0)
			{
			EVP_DigestInit_ex(&md,EVP_md5(), NULL);
			EVP_DigestUpdate(&md,er1,SSL3_RANDOM_SIZE);
			EVP_DigestUpdate(&md,er2,SSL3_RANDOM_SIZE);
			EVP_DigestFinal_ex(&md,&(exp_iv[0]),NULL);
			iv= &(exp_iv[0]);
			}
		}

	s->session->key_arg_length=0;

	EVP_CipherInit_ex(dd,c,NULL,key,iv,(which & SSL3_CC_WRITE));

	OPENSSL_cleanse(&(exp_key[0]),sizeof(exp_key));
	OPENSSL_cleanse(&(exp_iv[0]),sizeof(exp_iv));
	EVP_MD_CTX_cleanup(&md);
	return(1);
err:
	SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,ERR_R_MALLOC_FAILURE);
err2:
	return(0);
	}
Exemplo n.º 21
0
static OM_uint32
unwrap_des
           (OM_uint32 * minor_status,
            const gsskrb5_ctx context_handle,
            const gss_buffer_t input_message_buffer,
            gss_buffer_t output_message_buffer,
            int * conf_state,
            gss_qop_t * qop_state,
	    krb5_keyblock *key
           )
{
  u_char *p, *seq;
  size_t len;
  EVP_MD_CTX *md5;
  u_char hash[16];
  EVP_CIPHER_CTX *des_ctx;
  DES_key_schedule schedule;
  DES_cblock deskey;
  DES_cblock zero;
  size_t i;
  uint32_t seq_number;
  size_t padlength;
  OM_uint32 ret;
  int cstate;
  int cmp;
  int token_len;

  if (IS_DCE_STYLE(context_handle)) {
     token_len = 22 + 8 + 15; /* 45 */
  } else {
     token_len = input_message_buffer->length;
  }

  p = input_message_buffer->value;
  ret = _gsskrb5_verify_header (&p,
				   token_len,
				   "\x02\x01",
				   GSS_KRB5_MECHANISM);
  if (ret)
      return ret;

  if (memcmp (p, "\x00\x00", 2) != 0)
    return GSS_S_BAD_SIG;
  p += 2;
  if (memcmp (p, "\x00\x00", 2) == 0) {
      cstate = 1;
  } else if (memcmp (p, "\xFF\xFF", 2) == 0) {
      cstate = 0;
  } else
      return GSS_S_BAD_MIC;
  p += 2;
  if(conf_state != NULL)
      *conf_state = cstate;
  if (memcmp (p, "\xff\xff", 2) != 0)
    return GSS_S_DEFECTIVE_TOKEN;
  p += 2;
  p += 16;

  len = p - (u_char *)input_message_buffer->value;

  if(cstate) {
      /* decrypt data */
      memcpy (&deskey, key->keyvalue.data, sizeof(deskey));
      memset (&zero, 0, sizeof(zero));

      for (i = 0; i < sizeof(deskey); ++i)
	  deskey[i] ^= 0xf0;


      des_ctx = EVP_CIPHER_CTX_new();
      if (des_ctx == NULL) {
	  memset (deskey, 0, sizeof(deskey));
	  *minor_status = ENOMEM;
	  return GSS_S_FAILURE;
      }
      EVP_CipherInit_ex(des_ctx, EVP_des_cbc(), NULL, deskey, zero, 0);
      EVP_Cipher(des_ctx, p, p, input_message_buffer->length - len);
      EVP_CIPHER_CTX_free(des_ctx);

      memset (deskey, 0, sizeof(deskey));
  }

  if (IS_DCE_STYLE(context_handle)) {
    padlength = 0;
  } else {
    /* check pad */
    ret = _gssapi_verify_pad(input_message_buffer,
			     input_message_buffer->length - len,
			     &padlength);
    if (ret)
        return ret;
  }

  md5 = EVP_MD_CTX_create();
  EVP_DigestInit_ex(md5, EVP_md5(), NULL);
  EVP_DigestUpdate(md5, p - 24, 8);
  EVP_DigestUpdate(md5, p, input_message_buffer->length - len);
  EVP_DigestFinal_ex(md5, hash, NULL);
  EVP_MD_CTX_destroy(md5);

  memset (&zero, 0, sizeof(zero));
  memcpy (&deskey, key->keyvalue.data, sizeof(deskey));
  DES_set_key_unchecked (&deskey, &schedule);
  DES_cbc_cksum ((void *)hash, (void *)hash, sizeof(hash),
		 &schedule, &zero);
  if (ct_memcmp (p - 8, hash, 8) != 0) {
    memset (deskey, 0, sizeof(deskey));
    memset (&schedule, 0, sizeof(schedule));
    return GSS_S_BAD_MIC;
  }

  /* verify sequence number */

  des_ctx = EVP_CIPHER_CTX_new();
  if (des_ctx == NULL) {
    memset (deskey, 0, sizeof(deskey));
    memset (&schedule, 0, sizeof(schedule));
    *minor_status = ENOMEM;
    return GSS_S_FAILURE;
  }

  HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);

  p -= 16;

  EVP_CipherInit_ex(des_ctx, EVP_des_cbc(), NULL, key->keyvalue.data, hash, 0);
  EVP_Cipher(des_ctx, p, p, 8);
  EVP_CIPHER_CTX_free(des_ctx);

  memset (deskey, 0, sizeof(deskey));
  memset (&schedule, 0, sizeof(schedule));

  seq = p;
  _gsskrb5_decode_om_uint32(seq, &seq_number);

  if (context_handle->more_flags & LOCAL)
      cmp = ct_memcmp(&seq[4], "\xff\xff\xff\xff", 4);
  else
      cmp = ct_memcmp(&seq[4], "\x00\x00\x00\x00", 4);

  if (cmp != 0) {
    HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
    return GSS_S_BAD_MIC;
  }

  ret = _gssapi_msg_order_check(context_handle->order, seq_number);
  if (ret) {
    HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
    return ret;
  }

  HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);

  /* copy out data */

  output_message_buffer->length = input_message_buffer->length
    - len - padlength - 8;
  output_message_buffer->value  = malloc(output_message_buffer->length);
  if(output_message_buffer->length != 0 && output_message_buffer->value == NULL)
      return GSS_S_FAILURE;
  memcpy (output_message_buffer->value,
	  p + 24,
	  output_message_buffer->length);
  return GSS_S_COMPLETE;
}
Exemplo n.º 22
0
void ssl3_finish_mac(SSL *s, const unsigned char *buf, int len)
	{
	EVP_DigestUpdate(&(s->s3->finish_dgst1),buf,len);
	EVP_DigestUpdate(&(s->s3->finish_dgst2),buf,len);
	}
Exemplo n.º 23
0
void EVP_SignUpdate(EVP_MD_CTX *ctx, unsigned char *data,
	     unsigned int count)
	{
	EVP_DigestUpdate(ctx,data,count);
	}
Exemplo n.º 24
0
Arquivo: hash.c Projeto: tlauda/sof
void module_sha256_update(struct image *image, uint8_t *data, size_t bytes)
{
	EVP_DigestUpdate(image->mdctx, data, bytes);
}
Exemplo n.º 25
0
int SM2_do_decrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
	const SM2_CIPHERTEXT_VALUE *cv, unsigned char *out, size_t *outlen,
	EC_KEY *ec_key)
{
	int ret = 0;
	const EC_GROUP *ec_group = EC_KEY_get0_group(ec_key);
	const BIGNUM *pri_key = EC_KEY_get0_private_key(ec_key);
	KDF_FUNC kdf = KDF_get_x9_63(kdf_md);
	EC_POINT *point = NULL;
	BIGNUM *n = NULL;
	BIGNUM *h = NULL;
	BN_CTX *bn_ctx = NULL;
	EVP_MD_CTX *md_ctx = NULL;
	unsigned char buf[(OPENSSL_ECC_MAX_FIELD_BITS + 7)/4 + 1];
	unsigned char mac[EVP_MAX_MD_SIZE];
	unsigned int maclen;
	int nbytes;
	size_t size;
	int i;

	OPENSSL_assert(kdf_md && mac_md && cv && ec_key);
	OPENSSL_assert(cv->ephem_point && cv->ciphertext);

	if (!ec_group || !pri_key) {
		goto end;
	}
	if (!kdf) {
		goto end;
	}

	if (!out) {
		*outlen = cv->ciphertext_size;
		return 1;
	}
	if (*outlen < cv->ciphertext_size) {
		goto end;
	}

	/* init vars */
	point = EC_POINT_new(ec_group);
	n = BN_new();
	h = BN_new();
	bn_ctx = BN_CTX_new();
	md_ctx = EVP_MD_CTX_create();
	if (!point || !n || !h || !bn_ctx || !md_ctx) {
		goto end;
	}
	
	/* init ec domain parameters */
	if (!EC_GROUP_get_order(ec_group, n, bn_ctx)) {
		goto end;
	}
	if (!EC_GROUP_get_cofactor(ec_group, h, bn_ctx)) {
		goto end;
	}
	nbytes = (EC_GROUP_get_degree(ec_group) + 7) / 8;
	//OPENSSL_assert(nbytes == BN_num_bytes(n));

#if 0
	/* check sm2 curve and md is 256 bits */
	OPENSSL_assert(nbytes == 32);
	OPENSSL_assert(EVP_MD_size(kdf_md) == 32);
	OPENSSL_assert(EVP_MD_size(mac_md) == 32);
#endif

	/* B2: check [h]C1 != O */
	if (!EC_POINT_mul(ec_group, point, NULL, cv->ephem_point, h, bn_ctx)) {
		goto end;
	}
	if (EC_POINT_is_at_infinity(ec_group, point)) {
		goto end;
	}

	/* B3: compute ECDH [d]C1 = (x2, y2) */	
	if (!EC_POINT_mul(ec_group, point, NULL, cv->ephem_point, pri_key, bn_ctx)) {
		goto end;
	}
	if (!(size = EC_POINT_point2oct(ec_group, point,
		POINT_CONVERSION_UNCOMPRESSED, buf, sizeof(buf), bn_ctx))) {
		goto end;
	}
	OPENSSL_assert(size == 1 + nbytes * 2);

	/* B4: compute t = KDF(x2 || y2, clen) */

	*outlen = cv->ciphertext_size; //FIXME: duplicated code
	kdf(buf + 1, size - 1, out, outlen);


	/* B5: compute M = C2 xor t */
	for (i = 0; i < cv->ciphertext_size; i++) {
		out[i] ^= cv->ciphertext[i];
	}
	*outlen = cv->ciphertext_size;

	/* B6: check Hash(x2 || M || y2) == C3 */
	if (!EVP_DigestInit_ex(md_ctx, mac_md, NULL)) {
		goto end;
	}
	if (!EVP_DigestUpdate(md_ctx, buf + 1, nbytes)) {
		goto end;
	}
	if (!EVP_DigestUpdate(md_ctx, out, *outlen)) {
		goto end;
	}
	if (!EVP_DigestUpdate(md_ctx, buf + 1 + nbytes, nbytes)) {
		goto end;
	}
	if (!EVP_DigestFinal_ex(md_ctx, mac, &maclen)) {
		goto end;
	}
	if (cv->mactag_size != maclen ||
		memcmp(cv->mactag, mac, maclen)) {
		goto end;
	}

	ret = 1;
end:
	if (point) EC_POINT_free(point);
	if (n) BN_free(n);	
	if (h) BN_free(h);
	if (bn_ctx) BN_CTX_free(bn_ctx);
	if (md_ctx) EVP_MD_CTX_destroy(md_ctx);

	return ret;
}
Exemplo n.º 26
0
/* Updates the digest context
 * Returns 1 if successful, 0 on failure or -1 on error
 */
int digest_context_update(
     digest_context_t *digest_context,
     uint8_t *buffer,
     size_t size,
     liberror_error_t **error )
{
	static char *function = "digest_context_update";

	if( digest_context == NULL )
	{
		liberror_error_set(
		 error,
		 LIBERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid digest context.",
		 function );

		return( -1 );
	}
	if( buffer == NULL )
	{
		liberror_error_set(
		 error,
		 LIBERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid buffer.",
		 function );

		return( -1 );
	}
	if( size > (size_t) SSIZE_MAX )
	{
		liberror_error_set(
		 error,
		 LIBERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
		 "%s: invalid size value exceeds maximum.",
		 function );

		return( -1 );
	}
#if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H )
	if( EVP_DigestUpdate(
	     digest_context,
	     (const void *) buffer,
	     (unsigned long) size ) != 1 )
	{
		liberror_error_set(
		 error,
		 LIBERROR_ERROR_DOMAIN_RUNTIME,
		 LIBERROR_RUNTIME_ERROR_SET_FAILED,
		 "%s: unable to update digest hash.",
		 function );

		return( 0 );
	}
#elif defined( HAVE_WINCPRYPT_H )
	if( digest_context->hash == 0 )
	{
		liberror_error_set(
		 error,
		 LIBERROR_ERROR_DOMAIN_RUNTIME,
		 LIBERROR_RUNTIME_ERROR_VALUE_MISSING,
		 "%s: invalid digest context - missing hash.",
		 function );

		return( -1 );
	}
	if( CryptHashData(
	     digest_context->hash,
	     (BYTE *) buffer,
	     (DWORD) size,
	     0 ) != 1 )
	{
		liberror_error_set(
		 error,
		 LIBERROR_ERROR_DOMAIN_RUNTIME,
		 LIBERROR_RUNTIME_ERROR_SET_FAILED,
		 "%s: unable to update digest context hash.",
		 function );

		return( 0 );
	}
#endif
	return( 1 );
}
Exemplo n.º 27
0
static int SSHKDF(const EVP_MD *evp_md,
                  const unsigned char *key, size_t key_len,
                  const unsigned char *xcghash, size_t xcghash_len,
                  const unsigned char *session_id, size_t session_id_len,
                  char type, unsigned char *okey, size_t okey_len)
{
    EVP_MD_CTX *md = NULL;
    unsigned char digest[EVP_MAX_MD_SIZE];
    unsigned int dsize = 0;
    size_t cursize = 0;
    int ret = 0;

    md = EVP_MD_CTX_new();
    if (md == NULL)
        return 0;

    if (!EVP_DigestInit_ex(md, evp_md, NULL))
        goto out;

    if (!EVP_DigestUpdate(md, key, key_len))
        goto out;

    if (!EVP_DigestUpdate(md, xcghash, xcghash_len))
        goto out;

    if (!EVP_DigestUpdate(md, &type, 1))
        goto out;

    if (!EVP_DigestUpdate(md, session_id, session_id_len))
        goto out;

    if (!EVP_DigestFinal_ex(md, digest, &dsize))
        goto out;

    if (okey_len < dsize) {
        memcpy(okey, digest, okey_len);
        ret = 1;
        goto out;
    }

    memcpy(okey, digest, dsize);

    for (cursize = dsize; cursize < okey_len; cursize += dsize) {

        if (!EVP_DigestInit_ex(md, evp_md, NULL))
            goto out;

        if (!EVP_DigestUpdate(md, key, key_len))
            goto out;

        if (!EVP_DigestUpdate(md, xcghash, xcghash_len))
            goto out;

        if (!EVP_DigestUpdate(md, okey, cursize))
            goto out;

        if (!EVP_DigestFinal_ex(md, digest, &dsize))
            goto out;

        if (okey_len < cursize + dsize) {
            memcpy(okey + cursize, digest, okey_len - cursize);
            ret = 1;
            goto out;
        }

        memcpy(okey + cursize, digest, dsize);
    }

    ret = 1;

out:
    EVP_MD_CTX_free(md);
    OPENSSL_cleanse(digest, EVP_MAX_MD_SIZE);
    return ret;
}
Exemplo n.º 28
0
                _SCAPI_NOT_CONFIGURED
#endif                          /* */
/*
 * sc_hash(): a generic wrapper around whatever hashing package we are using.
 * 
 * IN:
 * hashtype    - oid pointer to a hash type
 * hashtypelen - length of oid pointer
 * buf         - u_char buffer to be hashed
 * buf_len     - integer length of buf data
 * MAC_len     - length of the passed MAC buffer size.
 * 
 * OUT:    
 * MAC         - pre-malloced space to store hash output.
 * MAC_len     - length of MAC output to the MAC buffer.
 * 
 * Returns:
 * SNMPERR_SUCCESS              Success.
 * SNMP_SC_GENERAL_FAILURE      Any error.
 */
int
sc_hash(const oid * hashtype, size_t hashtypelen, u_char * buf,
        size_t buf_len, u_char * MAC, size_t * MAC_len)
#if defined(USE_INTERNAL_MD5) || defined(USE_OPENSSL)
{
#ifdef USE_OPENSSL
    int             rval = SNMPERR_SUCCESS;
    const EVP_MD         *hashfn;
    EVP_MD_CTX     ctx, *cptr;
#endif

    DEBUGTRACE;

    if (hashtype == NULL || hashtypelen < 0 || buf == NULL ||
        buf_len < 0 || MAC == NULL || MAC_len == NULL ||
        (int) (*MAC_len) < sc_get_properlength(hashtype, hashtypelen))
        return (SNMPERR_GENERR);

#ifdef USE_OPENSSL
    /*
     * Determine transform type.
     */
    if (ISTRANSFORM(hashtype, HMACMD5Auth)) {
        hashfn = (const EVP_MD *) EVP_md5();
    } else if (ISTRANSFORM(hashtype, HMACSHA1Auth)) {
        hashfn = (const EVP_MD *) EVP_sha1();
    } else {
        return (SNMPERR_GENERR);
    }

/** initialize the pointer */
    memset(&ctx, 0, sizeof(ctx));
    cptr = &ctx;
#if defined(OLD_DES)
    EVP_DigestInit(cptr, hashfn);
#else /* !OLD_DES */
    /* this is needed if the runtime library is different than the compiled
       library since the openssl versions are very different. */
    if (SSLeay() < 0x907000) {
        /* the old version of the struct was bigger and thus more
           memory is needed. should be 152, but we use 256 for safety. */
        cptr = malloc(256);
        EVP_DigestInit(cptr, hashfn);
    } else {
        EVP_MD_CTX_init(cptr);
        EVP_DigestInit(cptr, hashfn);
    }
#endif

/** pass the data */
    EVP_DigestUpdate(cptr, buf, buf_len);

/** do the final pass */
#if defined(OLD_DES)
    EVP_DigestFinal(cptr, MAC, MAC_len);
#else /* !OLD_DES */
    if (SSLeay() < 0x907000) {
        EVP_DigestFinal(cptr, MAC, MAC_len);
        free(cptr);
    } else {
        EVP_DigestFinal_ex(cptr, MAC, MAC_len);
        EVP_MD_CTX_cleanup(cptr);
    }
#endif
    return (rval);
#else                           /* USE_INTERNAL_MD5 */

    if (MDchecksum(buf, buf_len, MAC, *MAC_len)) {
        return SNMPERR_GENERR;
    }
    if (*MAC_len > 16)
        *MAC_len = 16;
    return SNMPERR_SUCCESS;

#endif                          /* USE_OPENSSL */
}
Exemplo n.º 29
0
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;
}
Exemplo n.º 30
0
char *
ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check,
    const char *data) {
	Buffer buf;
	size_t i;
	int oidpos, enclen;
	char *mechs, *encoded;
	u_char digest[EVP_MAX_MD_SIZE];
	char deroid[2];
	const EVP_MD *evp_md = EVP_md5();
	EVP_MD_CTX md;

	if (gss_enc2oid != NULL) {
		for (i = 0; gss_enc2oid[i].encoded != NULL; i++)
			xfree(gss_enc2oid[i].encoded);
		xfree(gss_enc2oid);
	}

	gss_enc2oid = xmalloc(sizeof(ssh_gss_kex_mapping) *
	    (gss_supported->count + 1));

	buffer_init(&buf);

	oidpos = 0;
	for (i = 0; i < gss_supported->count; i++) {
		if (gss_supported->elements[i].length < 128 &&
		    (*check)(NULL, &(gss_supported->elements[i]), data)) {

			deroid[0] = SSH_GSS_OIDTYPE;
			deroid[1] = gss_supported->elements[i].length;

			EVP_DigestInit(&md, evp_md);
			EVP_DigestUpdate(&md, deroid, 2);
			EVP_DigestUpdate(&md,
			    gss_supported->elements[i].elements,
			    gss_supported->elements[i].length);
			EVP_DigestFinal(&md, digest, NULL);

			encoded = xmalloc(EVP_MD_size(evp_md) * 2);
			enclen = __b64_ntop(digest, EVP_MD_size(evp_md),
			    encoded, EVP_MD_size(evp_md) * 2);

			if (oidpos != 0)
				buffer_put_char(&buf, ',');

			buffer_append(&buf, KEX_GSS_GEX_SHA1_ID,
			    sizeof(KEX_GSS_GEX_SHA1_ID) - 1);
			buffer_append(&buf, encoded, enclen);
			buffer_put_char(&buf, ',');
			buffer_append(&buf, KEX_GSS_GRP1_SHA1_ID, 
			    sizeof(KEX_GSS_GRP1_SHA1_ID) - 1);
			buffer_append(&buf, encoded, enclen);
			buffer_put_char(&buf, ',');
			buffer_append(&buf, KEX_GSS_GRP14_SHA1_ID,
			    sizeof(KEX_GSS_GRP14_SHA1_ID) - 1);
			buffer_append(&buf, encoded, enclen);

			gss_enc2oid[oidpos].oid = &(gss_supported->elements[i]);
			gss_enc2oid[oidpos].encoded = encoded;
			oidpos++;
		}
	}
	gss_enc2oid[oidpos].oid = NULL;
	gss_enc2oid[oidpos].encoded = NULL;

	buffer_put_char(&buf, '\0');

	mechs = xmalloc(buffer_len(&buf));
	buffer_get(&buf, mechs, buffer_len(&buf));
	buffer_free(&buf);

	if (strlen(mechs) == 0) {
		xfree(mechs);
		mechs = NULL;
	}
	
	return (mechs);
}