static TEE_Result do_hmac(void *out_key, size_t out_key_size, const void *in_key, size_t in_key_size, const void *message, size_t message_size) { TEE_Result res; void *ctx = NULL; if (!out_key || !in_key || !message) return TEE_ERROR_BAD_PARAMETERS; res = crypto_mac_alloc_ctx(&ctx, TEE_FS_KM_HMAC_ALG); if (res != TEE_SUCCESS) return res; res = crypto_mac_init(ctx, TEE_FS_KM_HMAC_ALG, in_key, in_key_size); if (res != TEE_SUCCESS) goto exit; res = crypto_mac_update(ctx, TEE_FS_KM_HMAC_ALG, message, message_size); if (res != TEE_SUCCESS) goto exit; res = crypto_mac_final(ctx, TEE_FS_KM_HMAC_ALG, out_key, out_key_size); if (res != TEE_SUCCESS) goto exit; res = TEE_SUCCESS; exit: crypto_mac_free_ctx(ctx, TEE_FS_KM_HMAC_ALG); return res; }
static TEE_Result pbkdf2_f(uint8_t *out, size_t len, uint32_t idx, struct hmac_parms *h, struct pbkdf2_parms *p) { TEE_Result res; uint8_t u[TEE_MAX_HASH_SIZE]; uint32_t be_index; size_t i, j; memset(out, 0, len); for (i = 1; i <= p->iteration_count; i++) { res = crypto_mac_init(h->ctx, h->algo, p->password, p->password_len); if (res != TEE_SUCCESS) return res; if (i == 1) { if (p->salt && p->salt_len) { res = crypto_mac_update(h->ctx, h->algo, p->salt, p->salt_len); if (res != TEE_SUCCESS) return res; } be_index = TEE_U32_TO_BIG_ENDIAN(idx); res = crypto_mac_update(h->ctx, h->algo, (uint8_t *)&be_index, sizeof(be_index)); if (res != TEE_SUCCESS) return res; } else { res = crypto_mac_update(h->ctx, h->algo, u, h->hash_len); if (res != TEE_SUCCESS) return res; } res = crypto_mac_final(h->ctx, h->algo, u, sizeof(u)); if (res != TEE_SUCCESS) return res; for (j = 0; j < len; j++) out[j] ^= u[j]; } return TEE_SUCCESS; }
/* * Digest one segment */ int smb3_cmac_update(smb_sign_ctx_t ctx, uint8_t *in, size_t len) { crypto_data_t data; int rv; bzero(&data, sizeof (data)); data.cd_format = CRYPTO_DATA_RAW; data.cd_length = len; data.cd_raw.iov_base = (void *)in; data.cd_raw.iov_len = len; rv = crypto_mac_update(ctx, &data, 0); return (rv == CRYPTO_SUCCESS ? 0 : -1); }
static int hkdf_sha512_expand(uint8_t *extract_key, uint8_t *info, uint_t info_len, uint8_t *out_buf, uint_t out_len) { int ret; crypto_mechanism_t mech; crypto_context_t ctx; crypto_key_t key; crypto_data_t T_cd, info_cd, c_cd; uint_t i, T_len = 0, pos = 0; uint8_t c; uint_t N = (out_len + SHA512_DIGEST_LENGTH) / SHA512_DIGEST_LENGTH; uint8_t T[SHA512_DIGEST_LENGTH]; if (N > 255) return (SET_ERROR(EINVAL)); /* initialize HMAC mechanism */ mech.cm_type = crypto_mech2id(SUN_CKM_SHA512_HMAC); mech.cm_param = NULL; mech.cm_param_len = 0; /* initialize the salt as a crypto key */ key.ck_format = CRYPTO_KEY_RAW; key.ck_length = CRYPTO_BYTES2BITS(SHA512_DIGEST_LENGTH); key.ck_data = extract_key; /* initialize crypto data for the input and output data */ T_cd.cd_format = CRYPTO_DATA_RAW; T_cd.cd_offset = 0; T_cd.cd_raw.iov_base = (char *)T; c_cd.cd_format = CRYPTO_DATA_RAW; c_cd.cd_offset = 0; c_cd.cd_length = 1; c_cd.cd_raw.iov_base = (char *)&c; c_cd.cd_raw.iov_len = c_cd.cd_length; info_cd.cd_format = CRYPTO_DATA_RAW; info_cd.cd_offset = 0; info_cd.cd_length = info_len; info_cd.cd_raw.iov_base = (char *)info; info_cd.cd_raw.iov_len = info_cd.cd_length; for (i = 1; i <= N; i++) { c = i; T_cd.cd_length = T_len; T_cd.cd_raw.iov_len = T_cd.cd_length; ret = crypto_mac_init(&mech, &key, NULL, &ctx, NULL); if (ret != CRYPTO_SUCCESS) return (SET_ERROR(EIO)); ret = crypto_mac_update(ctx, &T_cd, NULL); if (ret != CRYPTO_SUCCESS) return (SET_ERROR(EIO)); ret = crypto_mac_update(ctx, &info_cd, NULL); if (ret != CRYPTO_SUCCESS) return (SET_ERROR(EIO)); ret = crypto_mac_update(ctx, &c_cd, NULL); if (ret != CRYPTO_SUCCESS) return (SET_ERROR(EIO)); T_len = SHA512_DIGEST_LENGTH; T_cd.cd_length = T_len; T_cd.cd_raw.iov_len = T_cd.cd_length; ret = crypto_mac_final(ctx, &T_cd, NULL); if (ret != CRYPTO_SUCCESS) return (SET_ERROR(EIO)); bcopy(T, out_buf + pos, (i != N) ? SHA512_DIGEST_LENGTH : (out_len - pos)); pos += SHA512_DIGEST_LENGTH; } return (0); }