Commit 9c27b2b3 authored by Geoff Simmons's avatar Geoff Simmons

Add the wipe() function.

parent 5f68951d
Pipeline #228 skipped
......@@ -38,6 +38,8 @@ import gcrypt [from "path"] ;
BLOB gcrypt.random([ENUM quality] [, BYTES n])
INT gcrypt.random_int(ENUM quality [, INT bound])
gcrypt.wipe(BLOB)
gcrypt.version()
gcrypt.gcrypt_version()
......@@ -88,6 +90,11 @@ This is a simple usage example::
# Create an object for AES-128 in CTR mode using the key just
# created, and with libgcrypt internal structures in secure memory.
new aes = gcrypt.symmetric(AES, CTR, key=k.get(), secure=true);
# Wipe the BLOB from which the key was read (overwrite the
# memory region with all zeroes), so that it is not stored in
# any non-secure memory.
gcrypt.wipe(key.get());
}
# Assume that a plaintext to be encrypted is in the response
......@@ -170,6 +177,7 @@ CONTENTS
* symmetric(ENUM {AES,AES128,RIJNDAEL,RIJNDAEL128,AES192,RIJNDAEL192,AES256,RIJNDAEL256}, ENUM {ECB,CFB,CBC,OFB,CTR}, ENUM {PKCS7,ISO7816,X923,NONE}, BLOB, BOOL, BOOL)
* BLOB random(PRIV_TASK, ENUM {STRONG,VERY_STRONG,NONCE}, BYTES)
* INT random_int(ENUM {STRONG,NONCE}, INT)
* VOID wipe(BLOB)
* STRING version()
* STRING gcrypt_version()
......@@ -627,6 +635,34 @@ Example::
# Assign a random group number from 0 to 99 to a request.
set req.http.X-Group = random_int(NONCE, 100);
.. _func_wipe:
wipe
----
::
VOID wipe(BLOB)
Overwrites the memory region denoted by the BLOB, leaving it with all
zeroes.
The BLOB MUST be non-empty. If ``wipe()`` is called with an empty
BLOB, then an error message is written to the log with the
``VCL_Error`` tag. If this happens in ``vcl_init``, then the VCL load
fails with the error message.
Example::
# After setting a symmetric encryption key, which will be stored in
# secure memory, wipe the BLOB from which the key was read. This
# ensures that the key is only stored in secure memory.
sub vcl_init {
new k = blobcode.blob(HEX, "000102030405060708090a0b0c0d0e0f");
new aes = gcrypt.symmetric(AES, CTR, key=k.get(), secure=true);
gcrypt.wipe(key.get());
}
.. _func_version:
version
......
# looks like -*- vcl -*-
varnishtest "wipe()"
varnish v1 -vcl {
import blobcode;
import gcrypt from "${vmod_topbuild}/src/.libs/libvmod_gcrypt.so";
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new b16
= blobcode.blob(HEX, "000102030405060708090a0b0c0d0e0f");
gcrypt.wipe(b16.get());
new b4 = blobcode.blob(HEX, "00010203");
gcrypt.wipe(b4.get());
new b12 = blobcode.blob(HEX, "000102030405060708090a0b");
gcrypt.wipe(b12.get());
new hobbes = blobcode.blob(IDENTITY,
"Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.");
gcrypt.wipe(hobbes.get());
new foo = blobcode.blob(encoded="foo");
new empty = blobcode.blob(encoded="");
}
sub vcl_recv {
return(synth(200));
}
sub vcl_synth {
set resp.http.b16 = blobcode.encode(HEXUC, b16.get());
set resp.http.b4 = blobcode.encode(HEXUC, b4.get());
set resp.http.b12 = blobcode.encode(HEXUC, b12.get());
set resp.http.hobbes = blobcode.encode(HEXUC, hobbes.get());
gcrypt.wipe(foo.get());
set resp.http.foo = blobcode.encode(HEXUC, foo.get());
gcrypt.wipe(empty.get());
return(deliver);
}
} -start
client c1 {
txreq
rxresp
expect resp.status == 200
expect resp.http.b16 == "00000000000000000000000000000000"
expect resp.http.b4 == "00000000"
expect resp.http.b12 == "000000000000000000000000"
expect resp.http.hobbes ~ "^0{538}$"
expect resp.http.foo == "000000"
} -run
logexpect l1 -v v1 -d 1 -q "VCL_Error" {
expect 0 * Begin req
expect * = VCL_Error "^vmod gcrypt error: empty blob in gcrypt.wipe..$"
expect * = End
} -run
varnish v1 -errvcl {vmod gcrypt error: empty blob in gcrypt.wipe()} {
import blobcode;
import gcrypt from "${vmod_topbuild}/src/.libs/libvmod_gcrypt.so";
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new empty = blobcode.blob(encoded="");
gcrypt.wipe(empty.get());
}
}
......@@ -759,6 +759,47 @@ vmod_random_int(VRT_CTX, VCL_ENUM qualitys, VCL_INT bound)
return r;
}
static inline void
wipe(void * const dst, size_t len, uint8_t val)
{
volatile uint8_t *p = (volatile uint8_t *)dst;
while (((uintptr_t)p & (sizeof(uint64_t)-1)) && len) {
*p = val;
p++;
len--;
}
if (len >= sizeof(uint64_t)) {
volatile uint64_t *p64;
uint64_t val64 = (uint64_t)0x0101010101010101 * val;
do {
p64 = (volatile void *)p;
*p64 = val64;
p += sizeof(uint64_t);
len -= sizeof(uint64_t);
} while (len >= sizeof(uint64_t));
}
while (len) {
*p = val;
p++;
len--;
}
}
VCL_VOID
vmod_wipe(VRT_CTX, VCL_BLOB b)
{
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
if (b == NULL || b->len == 0 || b->priv == NULL) {
ERR(ctx, "empty blob in gcrypt.wipe()");
return;
}
wipe(b->priv, b->len, 0xff);
wipe(b->priv, b->len, 0xaa);
wipe(b->priv, b->len, 0x55);
wipe(b->priv, b->len, 0x00);
}
VCL_STRING
vmod_version(VRT_CTX __attribute__((unused)))
{
......
......@@ -21,6 +21,8 @@ $Module gcrypt 3 access the libgcrypt cryptographic library
BLOB gcrypt.random([ENUM quality] [, BYTES n])
INT gcrypt.random_int(ENUM quality [, INT bound])
gcrypt.wipe(BLOB)
gcrypt.version()
gcrypt.gcrypt_version()
......@@ -71,6 +73,11 @@ This is a simple usage example::
# Create an object for AES-128 in CTR mode using the key just
# created, and with libgcrypt internal structures in secure memory.
new aes = gcrypt.symmetric(AES, CTR, key=k.get(), secure=true);
# Wipe the BLOB from which the key was read (overwrite the
# memory region with all zeroes), so that it is not stored in
# any non-secure memory.
gcrypt.wipe(key.get());
}
# Assume that a plaintext to be encrypted is in the response
......@@ -562,6 +569,27 @@ Example::
# Assign a random group number from 0 to 99 to a request.
set req.http.X-Group = random_int(NONCE, 100);
$Function VOID wipe(BLOB)
Overwrites the memory region denoted by the BLOB, leaving it with all
zeroes.
The BLOB MUST be non-empty. If ``wipe()`` is called with an empty
BLOB, then an error message is written to the log with the
``VCL_Error`` tag. If this happens in ``vcl_init``, then the VCL load
fails with the error message.
Example::
# After setting a symmetric encryption key, which will be stored in
# secure memory, wipe the BLOB from which the key was read. This
# ensures that the key is only stored in secure memory.
sub vcl_init {
new k = blobcode.blob(HEX, "000102030405060708090a0b0c0d0e0f");
new aes = gcrypt.symmetric(AES, CTR, key=k.get(), secure=true);
gcrypt.wipe(key.get());
}
$Function STRING version()
Returns the version string for this VMOD.
......
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