Commit e834e299 authored by Geoff Simmons's avatar Geoff Simmons

Decrypt VFP can read multiple records per fetch chunk.

This entails having a max_chunk parameter, currently hard-wired to
match default fetch_chunksize, but will become configurable.

In a perfect world, max_chunk would be automatically set to the
current value of fetch_chunksize -- setting it larger would be
unsafe. But since we can't read cache_param without violating
the API, we can only warn users not to do that. *sigh*
parent c5c81240
......@@ -40,6 +40,9 @@
#define HDR_PREFIX_LEN (SALT_LEN + 4 + 1)
#define ID_LEN 255
/* XXX currently hard-wired, will be configurable */
/* matches default fetch_chunksize */
#define DEFAULT_MAX_CHUNK (16 * 1024)
#define ERR_DEC(ctx, msg) \
VFP_Error((ctx), "ece decrypt: " msg)
......@@ -61,6 +64,7 @@ struct ece {
struct ece_crypto *crypto;
EVP_CIPHER_CTX *ectx;
uint8_t *buf;
size_t fetchsz;
uint64_t seq_lo;
uint32_t seq_hi;
uint32_t rs;
......@@ -163,6 +167,10 @@ decrypt_init(struct ece *ece, struct vfp_ctx *ctx)
ece->crypto->prenonce_hi = vbe32dec(prenonce);
ece->crypto->prenonce_lo = vbe64dec(prenonce + 4);
/* XXX make max_chunk configurable */
ece->fetchsz = (DEFAULT_MAX_CHUNK / ece->rs) * ece->rs;
if (ece->fetchsz == 0)
ece->fetchsz = ece->rs;
memcpy(ece->crypto->cek, cek, AES128_KEYLEN);
return (VFP_OK);
}
......@@ -312,7 +320,8 @@ vfp_decrypt_pull(struct vfp_ctx *ctx, struct vfp_entry *ent, void *ptr,
{
struct ece *ece;
size_t len;
enum vfp_status vp;
void *p = ptr;
enum vfp_status vp, fetch_vp;
CHECK_OBJ_NOTNULL(ctx, VFP_CTX_MAGIC);
CHECK_OBJ_NOTNULL(ent, VFP_ENTRY_MAGIC);
......@@ -320,19 +329,30 @@ vfp_decrypt_pull(struct vfp_ctx *ctx, struct vfp_entry *ent, void *ptr,
AN(ptr);
AN(lenp);
*lenp = 0;
if (ece->rs == 0)
if ((vp = decrypt_init(ece, ctx)) != VFP_OK)
return (vp);
AN(ece->rs);
AN(ece->fetchsz);
AN(ece->buf);
len = ece->rs;
vp = suck_bytes(ctx, ece->buf, &len);
assert(len <= ece->rs);
if (vp == VFP_ERROR)
return (vp);
vp = decrypt(ece, ctx, ptr, &len, vp);
*lenp = len;
len = ece->fetchsz;
fetch_vp = suck_bytes(ctx, ece->buf, &len);
if (fetch_vp == VFP_ERROR)
return (fetch_vp);
for (size_t in = len; vp == VFP_OK && in > 0; ece->buf += ece->rs) {
len = ece->rs;
if (in < len)
len = in;
vp = VFP_OK;
if (in <= ece->rs)
vp = fetch_vp;
in -= len;
vp = decrypt(ece, ctx, p, &len, vp);
p += len;
}
*lenp = p - ptr;
return (vp);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment