CCDigestRef digestRef_from_name(const char* name, unsigned int *outHashSize) { CCDigestRef result = NULL; if (NULL != outHashSize) *outHashSize = 0; if (0 == strcasecmp(name, "sha512")) { result = CCDigestCreate(kCCDigestSHA512); if (NULL != outHashSize) *outHashSize = CC_SHA512_DIGEST_LENGTH; } else if (0 == strcasecmp(name, "sha256")) { result = CCDigestCreate(kCCDigestSHA256); if (NULL != outHashSize) *outHashSize = CC_SHA256_DIGEST_LENGTH; } else if (0 == strcasecmp(name, "sha") || !strcasecmp(name, "sha1")) { result = CCDigestCreate(kCCDigestSHA1); if (NULL != outHashSize) *outHashSize = CC_SHA1_DIGEST_LENGTH; } else if (0 == strcasecmp(name, "md5")) { result = CCDigestCreate(kCCDigestMD5); if (NULL != outHashSize) *outHashSize = CC_MD5_DIGEST_LENGTH; } else if (0 == strcasecmp(name, "md2")) { result = CCDigestCreate(kCCDigestMD2); if (NULL != outHashSize) *outHashSize = CC_MD2_DIGEST_LENGTH; } return result; }
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); }
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; }
// // CommonCrypto-based DynamicHash instances // CCHashInstance::CCHashInstance(CCDigestAlg alg) { if (!(mDigest = CCDigestCreate(alg))) UnixError::throwMe(ENOMEM); }
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; }
// // CommonCrypto-based DynamicHash instances // CCHashInstance::CCHashInstance(CCDigestAlg alg, size_t truncate) { if (!(mDigest = CCDigestCreate(alg))) UnixError::throwMe(ENOMEM); mTruncate = truncate; }