krb5_error_code
_krb5_des_checksum(krb5_context context,
		   CCDigestAlg alg,
		   struct _krb5_key_data *key,
		   const void *data,
		   size_t len,
		   Checksum *cksum)
{
    struct _krb5_evp_schedule *ctx = key->schedule->data;
    CCDigestRef m;
    unsigned char ivec[8];
    unsigned char *p = cksum->checksum.data;

    krb5_generate_random_block(p, 8);

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

    CCDigestUpdate(m, p, 8);
    CCDigestUpdate(m, data, len);
    CCDigestFinal(m, p + 8);
    CCDigestDestroy(m);
    memset (&ivec, 0, sizeof(ivec));
    EVP_CipherInit_ex(&ctx->ectx, NULL, NULL, NULL, (void *)ivec, -1);
    EVP_Cipher(&ctx->ectx, p, p, 24);

    return 0;
}
static void DigestInChunks(CCDigestAlgorithm algorithm, size_t chunksize, const uint8_t *bytesToDigest, size_t numbytes, uint8_t *outbuf)
{
    CCDigestRef d = CCDigestCreate(algorithm);
    while(numbytes) {
        size_t n = (numbytes < chunksize) ? numbytes: chunksize;
        CCDigestUpdate(d, bytesToDigest, n);
        numbytes -= n;
        bytesToDigest += n;
    }
    if(CCDigestFinal(d, outbuf)) return;
    CCDigestDestroy(d);
}
Пример #3
0
Файл: hash.c Проект: aosm/xar
void *xar_hash_finish(xar_hash_t hash, size_t *nbyte) {
#ifdef __APPLE__
	void *buffer = calloc(1, CC_SHA512_DIGEST_LENGTH); // current biggest digest size  This is what OpenSSL uses
#else
	void *buffer = calloc(1, EVP_MAX_MD_SIZE);
#endif
	if( ! buffer )
		return NULL;
	
#ifdef __APPLE__
	CCDigestFinal(HASH_CTX(hash)->digest, buffer);
	CCDigestDestroy(HASH_CTX(hash)->digest);
#else
	EVP_DigestFinal(&HASH_CTX(hash)->digest, buffer, &HASH_CTX(hash)->length);
#endif
	
	*nbyte = HASH_CTX(hash)->length;
	free((void *)HASH_CTX(hash)->digest_name);
	free((void *)hash);
	return buffer;
}
krb5_error_code
_krb5_des_verify(krb5_context context,
		 CCDigestAlg alg,
		 struct _krb5_key_data *key,
		 const void *data,
		 size_t len,
		 Checksum *C)
{
    struct _krb5_evp_schedule *ctx = key->schedule->data;
    CCDigestRef m;
    unsigned char tmp[24];
    unsigned char res[16];
    unsigned char ivec[8];
    krb5_error_code ret = 0;

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

    memset(ivec, 0, sizeof(ivec));
    EVP_CipherInit_ex(&ctx->dctx, NULL, NULL, NULL, (void *)ivec, -1);
    EVP_Cipher(&ctx->dctx, tmp, C->checksum.data, 24);

    CCDigestUpdate(m, tmp, 8); /* confounder */
    CCDigestUpdate(m, data, len);
    CCDigestFinal(m, res);
    CCDigestDestroy(m);
    if(ct_memcmp(res, tmp + 8, sizeof(res)) != 0) {
	krb5_clear_error_message (context);
	ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
    }
    memset(tmp, 0, sizeof(tmp));
    memset(res, 0, sizeof(res));
    return ret;
}
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[CC_SHA1_DIGEST_LENGTH];
    CCDigestRef 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 = CCDigestCreate(kCCDigestSHA1);
    if (m == NULL) {
	free(keydata);
	krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
	return ENOMEM;
    }

    counter = 0;
    offset = 0;
    do {

	CCDigestReset(m);
	CCDigestUpdate(m, &counter, 1);
	CCDigestUpdate(m, dhdata, dhsize);

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

	CCDigestFinal(m, shaoutput);

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

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

    CCDigestDestroy(m);

    ret = krb5_random_to_key(context, type, keydata, keylen, key);
    memset(keydata, 0, sizeof(keylen));
    free(keydata);
    return ret;
}
krb5_error_code
_krb5_pk_kdf(krb5_context context,
	     const struct AlgorithmIdentifier *ai,
	     const void *dhdata,
	     size_t dhsize,
	     krb5_const_principal client,
	     krb5_const_principal server,
	     krb5_enctype enctype,
	     const krb5_data *as_req,
	     const krb5_data *pk_as_rep,
	     const Ticket *ticket,
	     krb5_keyblock *key)
{
    struct _krb5_encryption_type *et;
    krb5_error_code ret;
    krb5_data other;
    size_t keylen, offset;
    uint32_t counter;
    unsigned char *keydata;
    unsigned char shaoutput[CC_SHA1_DIGEST_LENGTH];
    CCDigestRef m;

    if (der_heim_oid_cmp(&asn1_oid_id_pkinit_kdf_ah_sha1, &ai->algorithm) != 0) {
	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 = CCDigestCreate(kCCDigestSHA1);
    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];

	CCDigestReset(m);
	_krb5_put_int(cdata, counter, 4);
	CCDigestUpdate(m, cdata, 4);
	CCDigestUpdate(m, dhdata, dhsize);
	CCDigestUpdate(m, other.data, other.length);

	CCDigestFinal(m, shaoutput);

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

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

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

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

    return ret;
}