- win32 keydata security via vm/MMF

John Kane jkane89 at softhome.net
Wed Jun 13 20:08:01 CEST 2001

There have been several requests for the code, so I'm putting
the core in the public record.  Werner & Timo have the rest.
There are two ways to use it. If you MMap entire pages, they
will be written only to the memory-mapped-file, not the main
swapfile. (I've used an MMF on a floppy; nothing is written
to the hard drive during a process swap.)  The program can
then burn the MMF with a clear conscience.  Users without 
secure memory may find this solution acceptable.
However, if you MMap 512 bytes, the remaining 3.5k in the 
page do not get written _anywhere_ during a swap. The parent 
routine can detect the loss of data and abort or restart.
I sent Timo a console utility which can be used to demonstrate 
this behavior; my scans of my swapfile show no stray copies.

Please note the following distinction:
  (1) A page can be locked IN memory to guarantee that it is
always accessible and never triggers a page fault.
  (2) A page can be protected to ensure that its contents
are never copied OUT of memory into permanent storage.
((This implements (2) in user code w/no kernel vxd.))

// win32vmSafe ALPHA.v0.2.1 - a 'no write to disk' volatile
// buffer implemented via standard win32 api calls.
// Copyright (c) 2001 John J. Kane <jkane89 at softhome.net>
#include <LGPL.license>
#include <windows.h>
static HANDLE FH, MH;
static unsigned char *pagepointer;

unsigned char* win32vmSafeInit(char *fName, int mapsize){
    FH = CreateFile(fName, GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_READ|FILE_SHARE_WRITE,  //(insecure)
        FILE_ATTRIBUTE_TEMPORARY, //minimizes flushing
    if (FH == INVALID_HANDLE_VALUE) return NULL;
    MH = CreateFileMapping(FH, NULL, PAGE_READWRITE, 0,
        mapsize, // sets # of bytes to swap back to disk
    if (MH == NULL) {
        return NULL;
    pagepointer = MapViewOfFile(MH, FILE_MAP_READ | 
        FILE_MAP_WRITE, 0, 0, 0);
    if (pagepointer == NULL) {
        CloseHandle(MH);  CloseHandle(FH);
        return NULL;
    } else {
        // ** A VirtualLock() here would limit swaps.
    return pagepointer;

void win32vmSafeFree(void) {
    // burn(); unlock();
    pagepointer = NULL;
    CloseHandle(MH);   MH = NULL;
    CloseHandle(FH);   FH = INVALID_HANDLE_VALUE;

More information about the Gnupg-devel mailing list