in source/caching_cmm.c [251:323]
int hash_enc_request(
struct aws_string *partition_id, struct aws_byte_buf *out, const struct aws_cryptosdk_enc_request *req) {
/*
* Here, we hash the relevant aspects of the request structure to use as a cache identifier.
* The hash is intended to match Java and Python, but since we've not yet committed to maintaining
* that parity indefinitely, we don't include this structure as part of the header API docs.
* The structure, internally, is:
* [partition ID hash]
* [0x01 if the request alg id is set, otherwise 0x00]
* [request alg id, if set]
* [serialized encryption context]
*/
struct aws_byte_buf context_buf = { 0 };
uint8_t digestbuf[AWS_CRYPTOSDK_MD_MAX_SIZE] = { 0 };
if (out->capacity < AWS_CRYPTOSDK_MD_MAX_SIZE) {
return aws_raise_error(AWS_ERROR_INVALID_BUFFER_SIZE);
}
struct aws_cryptosdk_md_context *md_context, *enc_ctx_md;
if (aws_cryptosdk_md_init(req->alloc, &md_context, AWS_CRYPTOSDK_MD_SHA512)) {
return AWS_OP_ERR;
}
if (aws_cryptosdk_md_init(req->alloc, &enc_ctx_md, AWS_CRYPTOSDK_MD_SHA512)) {
return AWS_OP_ERR;
}
if (aws_cryptosdk_md_update(md_context, aws_string_bytes(partition_id), partition_id->len)) {
goto md_err;
}
uint8_t requested_alg_present = req->requested_alg != 0;
if (aws_cryptosdk_md_update(md_context, &requested_alg_present, 1)) {
goto md_err;
}
if (requested_alg_present) {
uint16_t alg_id = aws_hton16(req->requested_alg);
if (aws_cryptosdk_md_update(md_context, &alg_id, sizeof(alg_id))) {
goto md_err;
}
}
size_t context_size;
if (aws_cryptosdk_enc_ctx_size(&context_size, req->enc_ctx) ||
aws_byte_buf_init(&context_buf, req->alloc, context_size) ||
aws_cryptosdk_enc_ctx_serialize(req->alloc, &context_buf, req->enc_ctx) ||
aws_cryptosdk_md_update(enc_ctx_md, context_buf.buffer, context_buf.len)) {
goto md_err;
}
size_t enc_ctx_digest_len;
if (aws_cryptosdk_md_finish(enc_ctx_md, digestbuf, &enc_ctx_digest_len)) {
enc_ctx_md = NULL;
goto md_err;
}
enc_ctx_md = NULL;
if (aws_cryptosdk_md_update(md_context, digestbuf, enc_ctx_digest_len)) {
goto md_err;
}
aws_byte_buf_clean_up(&context_buf);
return aws_cryptosdk_md_finish(md_context, out->buffer, &out->len);
md_err:
aws_byte_buf_clean_up(&context_buf);
aws_cryptosdk_md_abort(md_context);
aws_cryptosdk_md_abort(enc_ctx_md);
return AWS_OP_ERR;
}