diff --git a/.gitignore b/.gitignore
index 59e4f29..cf03caa 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,22 +1,27 @@
-*.o
 *.a
-config.*
+*.o
+*.swp
 *Makefile
 *Makefile.in
-aclocal.m4
 .deps/
-m4/
+aclocal.m4
 autom4te.cache/
+compile
+config.*
 configure
 depcomp
 install-sh
 libtool
 ltmain.sh
+m4/
 missing
+stamp-h1
+whitelist.c
+vbetool/.dirstamp
+
 resume
 s2both
 s2disk
 s2ram
-stamp-h1
+suspend-keygen
 swap-offset
-whitelist.c
diff --git a/Makefile.am b/Makefile.am
index 76a041d..5f247b3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -5,7 +5,7 @@
 #
 # This file is released under the GPLv2.
 #
-AUTOMAKE_OPTIONS=foreign dist-bzip2
+AUTOMAKE_OPTIONS=foreign dist-bzip2 subdir-objects
 
 MAINTAINERCLEANFILES = \
 	config.log config.status \
diff --git a/configure.ac b/configure.ac
index 9172296..5f3adb5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -8,8 +8,8 @@
 
 AC_PREREQ([2.59])
 AC_INIT([suspend-utils], [1.0])
-AM_INIT_AUTOMAKE([${PACKAGE_NAME}], [${PACKAGE_VERSION}])
-AM_CONFIG_HEADER([config.h])
+AM_INIT_AUTOMAKE
+AC_CONFIG_HEADERS([config.h])
 AC_CONFIG_SRCDIR([suspend.c])
 AC_CONFIG_MACRO_DIR([m4])
 
@@ -211,15 +211,7 @@ fi
 if test "${enable_encrypt}" = "yes"; then
 	CONFIG_FEATURES="${CONFIG_FEATURES} encrypt"
 	AC_DEFINE([CONFIG_ENCRYPT], [1], [Define if encryption enabled])
-
-	AC_MSG_CHECKING([for libgcrypt])
-	if ! test -x "${with_libgcrypt_prefix}/bin/libgcrypt-config"; then
-		AC_MSG_ERROR([Cannot locate libgcrypt])
-	else
-		AC_MSG_RESULT([found])
-		LIBGCRYPT_CFLAGS=`"${with_libgcrypt_prefix}/bin/libgcrypt-config" --cflags`
-		LIBGCRYPT_LIBS=`"${with_libgcrypt_prefix}/bin/libgcrypt-config" --libs`
-	fi
+	AM_PATH_LIBGCRYPT([1:1.6.3], [], [AC_MSG_ERROR([Cannot locate >=libgcrypt-1.6.3])])
 fi
 
 if test "${enable_splashy}" = "yes"; then
@@ -245,12 +237,14 @@ if test "${enable_fbsplash}" = "yes"; then
 	CONFIG_FEATURES="${CONFIG_FEATURES} fbsplash"
 	AC_DEFINE([CONFIG_FBSPLASH], [1], [Define if fbsplash enabled])
 
+    PKG_CONFIG="pkg-config --static"
 	PKG_CHECK_MODULES(
 		[FBSPLASH],
 		[libfbsplashrender >= 0.1],
 		,
 		[AC_MSG_ERROR([Required libfbsplashrender was not found])]
 	)
+    unset PKG_CONFIG
 fi
 
 if test "${enable_threads}" = "yes"; then
@@ -275,6 +269,7 @@ AC_CHECK_HEADERS([ \
 	stdint.h \
 ])
 
+CFLAGS="${CFLAGS} -std=gnu90"
 if test "${enable_pedantic}" = "yes"; then
 	enable_strict="yes";
 	CFLAGS="${CFLAGS} -pedantic"
diff --git a/keygen.c b/keygen.c
index 7cfae65..b2e0724 100644
--- a/keygen.c
+++ b/keygen.c
@@ -36,12 +36,7 @@ static unsigned char encrypt_buffer[RSA_DATA_SIZE];
 
 int main(int argc, char *argv[])
 {
-	gcry_ac_data_t rsa_data_set;
-	gcry_ac_handle_t rsa_hd;
-	gcry_ac_key_t rsa_priv;
-	gcry_ac_key_pair_t rsa_key_pair;
-	gcry_mpi_t mpi;
-	size_t offset;
+	gcry_sexp_t rsa_pair, rsa_spec, rsa_priv;
 	int len = MIN_KEY_BITS, ret = EXIT_SUCCESS;
 	struct termios termios;
 	char *vrfy_buf;
@@ -51,67 +46,48 @@ int main(int argc, char *argv[])
 	unsigned char ivec[PK_CIPHER_BLOCK];
 	unsigned short size;
 	int j, fd;
+	const char *rsa_keys="nedpqu";
 
 	printf("libgcrypt version: %s\n", gcry_check_version(NULL));
 	gcry_control(GCRYCTL_INIT_SECMEM, 4096, 0);
-	ret = gcry_ac_open(&rsa_hd, GCRY_AC_RSA, 0);
-	if (ret)
-		return ret;
 
 	do {
-		printf("Key bits (between %d and %d inclusive) [%d]: ",
+		printf("Key bits (between %d and %d inclusive, must be multiple of 8) [%d]: ",
 			MIN_KEY_BITS, MAX_KEY_BITS, len);
 		fgets(in_buffer, MAX_STR_LEN, stdin);
 		if (strlen(in_buffer) && *in_buffer != '\n')
 			sscanf(in_buffer, "%d", &len);
-	} while (len < MIN_KEY_BITS || len > MAX_KEY_BITS);
+	} while (len < MIN_KEY_BITS || len > MAX_KEY_BITS || len % 8);
+
+	ret = gcry_sexp_build(&rsa_spec, NULL, "(genkey (rsa (nbits %u)))", len);
+	if (ret) {
+		fprintf(stderr, "Key parameters generation failed: %s\n", gcry_strerror(ret));
+		return ret;
+	}
 
 Retry:
 	printf("Generating %d-bit RSA keys.  Please wait.\n", len);
-	ret = gcry_ac_key_pair_generate(rsa_hd, len, NULL, &rsa_key_pair, NULL);
+	ret = gcry_pk_genkey(&rsa_pair, rsa_spec);
 	if (ret) {
 		fprintf(stderr, "Key generation failed: %s\n", gcry_strerror(ret));
+		goto Free_RSA_spec;
+	}
+	rsa_priv = gcry_sexp_find_token(rsa_pair, "private-key", 0);
+	if (!rsa_priv) {
+		fputs("Key generation failed: private key not found\n", stderr);
 		ret = EXIT_FAILURE;
-		goto Close_RSA;
+		goto Free_RSA_pair;
 	}
 	printf("Testing the private key.  Please wait.\n");
-	rsa_priv = gcry_ac_key_pair_extract(rsa_key_pair, GCRY_AC_KEY_SECRET);
-	ret = gcry_ac_key_test(rsa_hd, rsa_priv);
+	ret = gcry_pk_testkey(rsa_priv);
 	if (ret) {
-		printf("RSA key test failed.  Retrying.\n");
+		fprintf(stderr, "RSA key test failed: %s. Retrying.\n", gcry_strerror(ret));
+		gcry_sexp_release(rsa_priv);
+		gcry_sexp_release(rsa_pair);
 		goto Retry;
 	}
 
-	rsa_data_set = gcry_ac_key_data_get(rsa_priv);
-	if (gcry_ac_data_length(rsa_data_set) != RSA_FIELDS) {
-		fprintf(stderr, "Wrong number of key fields\n");
-		ret = -EINVAL;
-		goto Free_RSA;
-	}
-
-	/* Copy the public key components to struct RSA_data */
-	offset = 0;
-	for (j = 0; j < RSA_FIELDS_PUB; j++) {
-		char *str;
-		size_t s;
-
-		gcry_ac_data_get_index(rsa_data_set, GCRY_AC_FLAG_COPY, j,
-					(const char **)&str, &mpi);
-		ret = gcry_mpi_print(GCRYMPI_FMT_USG, rsa.data + offset,
-					RSA_DATA_SIZE - offset, &s, mpi);
-		if (ret) {
-			fprintf(stderr, "RSA key components too big\n");
-			goto Free_RSA;
-		}
-
-		rsa.field[j][0] = str[0];
-		rsa.field[j][1] = '\0';
-		rsa.size[j] = s;
-		offset += s;
-		gcry_mpi_release(mpi);
-		gcry_free(str);
-	}
-
+	// read password
 	tcgetattr(0, &termios);
 	termios.c_lflag &= ~ECHO;
 	termios.c_lflag |= ICANON | ECHONL;
@@ -142,8 +118,10 @@ Retry:
 	/* First, we encrypt the key test */
 	ret = gcry_cipher_open(&sym_hd, PK_CIPHER, GCRY_CIPHER_MODE_CFB,
 				GCRY_CIPHER_SECURE);
-	if (ret)
+	if (ret) {
+		fprintf(stderr, "Failed to open cipher: %s\n", gcry_strerror(ret));
 		goto Free_RSA;
+	}
 
 	ret = gcry_cipher_setkey(sym_hd, key_buf, PK_KEY_SIZE);
 	if (!ret)
@@ -154,48 +132,78 @@ Retry:
 					KEY_TEST_DATA, KEY_TEST_SIZE);
 
 	gcry_cipher_close(sym_hd);
-	if (ret)
+	if (ret) {
+		fprintf(stderr, "Failed to init cipher: %s\n", gcry_strerror(ret));
 		goto Free_RSA;
+	}
 
 	/* Now, we can encrypt the private RSA key */
 	ret = gcry_cipher_open(&sym_hd, PK_CIPHER, GCRY_CIPHER_MODE_CFB,
 				GCRY_CIPHER_SECURE);
-	if (ret)
+	if (ret) {
+		fprintf(stderr, "Failed to open cipher: %s\n", gcry_strerror(ret));
 		goto Free_RSA;
+	}
 
 	ret = gcry_cipher_setkey(sym_hd, key_buf, PK_KEY_SIZE);
 	if (!ret)
 		ret = gcry_cipher_setiv(sym_hd, ivec, PK_CIPHER_BLOCK);
 
-	if (ret)
+	if (ret) {
+		fprintf(stderr, "Failed to init cipher: %s\n", gcry_strerror(ret));
 		goto Free_sym;
+	}
+
+	/* Copy the key components to struct RSA_data */
+	size_t s, offset = 0;
+	gcry_sexp_t token;
+	gcry_mpi_t mpi;
+	for (j = 0; j < RSA_FIELDS && !ret; j++) {
 
-	/* Copy the private key components (encrypted) to struct RSA_data */
-	for (j = RSA_FIELDS_PUB; j < RSA_FIELDS; j++) {
-		char *str;
-		size_t s;
+		rsa.field[j][0] = rsa_keys[j];
+		rsa.field[j][1] = '\0';
 
-		gcry_ac_data_get_index(rsa_data_set, GCRY_AC_FLAG_COPY, j,
-					(const char **)&str, &mpi);
+		// now get S-expression for each parameter...
+		token = gcry_sexp_find_token(rsa_priv, rsa.field[j], 0);
+		if (!token) {
+			fprintf(stderr, "Can't find RSA parameter %s\n", rsa.field[j]);
+			ret = -EINVAL;
+			break;
+		}
+		// read RSA parameter
+		mpi = gcry_sexp_nth_mpi(token, 1, GCRYMPI_FMT_USG);
+		if (!mpi) {
+			fprintf(stderr, "Can't parse RSA parameter %s, idx %i\n", rsa.field[j], j);
+			ret = -EINVAL;
+			goto Release_token;
+		}
+		// write parameter to RSA buffer
 		ret = gcry_mpi_print(GCRYMPI_FMT_USG, rsa.data + offset,
 					RSA_DATA_SIZE - offset, &s, mpi);
 		if (ret) {
-			fprintf(stderr, "RSA key components too big\n");
-			goto Free_sym;
+			fprintf(stderr, "RSA key components too big: %s\n", gcry_strerror(ret));
+			goto Release_mpi;
 		}
 
-		/* We encrypt the data in place */
-		ret = gcry_cipher_encrypt(sym_hd, rsa.data + offset, s, NULL, 0);
-		if (ret)
-			goto Free_sym;
+		/* Encrypt private RSA components in place */
+		if (j >= RSA_FIELDS_PUB) {
+			ret = gcry_cipher_encrypt(sym_hd, rsa.data + offset, s, NULL, 0);
+			if (ret) {
+				fprintf(stderr, "Failed to encrypt RSA key: %s\n", gcry_strerror(ret));
+				goto Release_mpi;
+			}
+		}
 
-		rsa.field[j][0] = str[0];
-		rsa.field[j][1] = '\0';
 		rsa.size[j] = s;
 		offset += s;
+
+	Release_mpi:
 		gcry_mpi_release(mpi);
-		gcry_free(str);
+	Release_token:
+		gcry_sexp_release(token);
 	}
+	if (ret)
+		goto Free_sym;
 
 	size = offset + sizeof(struct RSA_data) - RSA_DATA_SIZE;
 
@@ -216,9 +224,11 @@ Retry:
 Free_sym:
 	gcry_cipher_close(sym_hd);
 Free_RSA:
-	gcry_ac_data_destroy(rsa_data_set);
-Close_RSA:
-	gcry_ac_close(rsa_hd);
+	gcry_sexp_release(rsa_priv);
+Free_RSA_pair:
+	gcry_sexp_release(rsa_pair);
+Free_RSA_spec:
+	gcry_sexp_release(rsa_spec);
 
 	return ret;
 }
diff --git a/load.c b/load.c
index 6d1c6ed..b7d20e6 100644
--- a/load.c
+++ b/load.c
@@ -168,7 +168,7 @@ static void free_swap_reader(struct swap_reader *handle)
  *	array of extents.
  */
 static int init_swap_reader(struct swap_reader *handle, int fd, loff_t start,
-                            loff_t image_size)
+							loff_t image_size)
 {
 	int error;
 
@@ -328,7 +328,7 @@ static ssize_t load_buffer(struct swap_reader *handle)
  *	@nr_pages:	Number of image data pages.
  */
 static int load_image(struct swap_reader *handle, int dev,
-                      unsigned int nr_pages, int verify_only)
+					  unsigned int nr_pages, int verify_only)
 {
 	unsigned int m, n;
 	ssize_t buf_size;
@@ -339,7 +339,7 @@ static int load_image(struct swap_reader *handle, int dev,
 
 	sprintf(message, "Loading image data pages (%u pages)...", nr_pages);
 	splash.set_caption(message);
-	printf("%s     ", message);
+	printf("%s	 ", message);
 
 	m = nr_pages / 100;
 	if (!m)
@@ -392,26 +392,22 @@ static char *print_checksum(char * buf, unsigned char *checksum)
 static int decrypt_key(struct image_header_info *header, unsigned char *key,
 			unsigned char *ivec)
 {
-	gcry_ac_handle_t rsa_hd;
-	gcry_ac_data_t rsa_data_set, key_set;
-	gcry_ac_key_t rsa_priv;
-	gcry_mpi_t mpi;
+	gcry_sexp_t rsa_priv, rsa_ciph, rsa_plain;
+	gcry_mpi_t mpi[RSA_FIELDS];
 	unsigned char *buf, *out, *key_buf, *ivec_buf;
 	struct md5_ctx ctx;
 	struct RSA_data *rsa;
 	gcry_cipher_hd_t sym_hd;
-	int j, ret;
+	int j, mi, ret;
 
 	rsa = &header->rsa;
 
-	ret = gcry_ac_open(&rsa_hd, GCRY_AC_RSA, 0);
-	if (ret)
-		return ret;
-
 	ret = gcry_cipher_open(&sym_hd, PK_CIPHER, GCRY_CIPHER_MODE_CFB,
 					GCRY_CIPHER_SECURE);
-	if (ret)
-		goto Free_rsa;
+	if (ret) {
+		fprintf(stderr, "Failed to init cipher: %s\n",  gcry_strerror(ret));
+		return ret;
+	}
 
 	key_buf = getmem(PK_KEY_SIZE);
 	ivec_buf = getmem(PK_CIPHER_BLOCK);
@@ -433,11 +429,8 @@ static int decrypt_key(struct image_header_info *header, unsigned char *key,
 						out, KEY_TEST_SIZE,
 						KEY_TEST_DATA, KEY_TEST_SIZE);
 
-		if (ret) {
-			fprintf(stderr, "%s: libgcrypt error: %s\n", my_name,
-					gcry_strerror(ret));
+		if (ret)
 			break;
-		}
 
 		ret = memcmp(out, rsa->key_test, KEY_TEST_SIZE);
 
@@ -449,98 +442,138 @@ static int decrypt_key(struct image_header_info *header, unsigned char *key,
 	if (!ret)
 		ret = gcry_cipher_open(&sym_hd, PK_CIPHER,
 				GCRY_CIPHER_MODE_CFB, GCRY_CIPHER_SECURE);
-	if (ret)
+	if (ret) {
+		fprintf(stderr, "%s: libgcrypt error: %s\n", my_name, gcry_strerror(ret));
 		goto Free_buffers;
+	}
 
 	ret = gcry_cipher_setkey(sym_hd, key_buf, PK_KEY_SIZE);
-	if (!ret)
-		ret = gcry_cipher_setiv(sym_hd, ivec_buf, PK_CIPHER_BLOCK);
-	if (!ret)
-		ret = gcry_ac_data_new(&rsa_data_set);
-	if (ret)
+	if (ret) {
+		fprintf(stderr, "Can't set cipher key: %s\n", gcry_strerror(ret));
+		goto Close_cypher;
+	}
+	ret = gcry_cipher_setiv(sym_hd, ivec_buf, PK_CIPHER_BLOCK);
+	if (ret) {
+		fprintf(stderr, "Can't set cipher iv: %s\n", gcry_strerror(ret));
 		goto Close_cypher;
+	}
 
+	// Retrieve RSA parameters
 	buf = rsa->data;
-	for (j = 0; j < RSA_FIELDS; j++) {
-		size_t s = rsa->size[j];
+	for (mi = 0; mi < RSA_FIELDS && !ret; mi++) {
+		size_t s = rsa->size[mi];
 
 		/* We need to decrypt some components */
-		if (j >= RSA_FIELDS_PUB) {
+		if (mi >= RSA_FIELDS_PUB) {
 			/* We use the in-place decryption */
 			ret = gcry_cipher_decrypt(sym_hd, buf, s, NULL, 0);
-			if (ret)
+			if (ret) {
+				fprintf(stderr, "Can't decrypt RSA parameters: %s\n", gcry_strerror(ret));
 				break;
+			}
 		}
 
-		gcry_mpi_scan(&mpi, GCRYMPI_FMT_USG, buf, s, NULL);
-		ret = gcry_ac_data_set(rsa_data_set, GCRY_AC_FLAG_COPY,
-					rsa->field[j], mpi);
-		gcry_mpi_release(mpi);
-		if (ret)
+		ret = gcry_mpi_scan(&mpi[mi], GCRYMPI_FMT_USG, buf, s, NULL);
+		if (ret) {
+			fprintf(stderr, "Can't parse RSA parameter %s: %s\n",
+					rsa->field[mi], gcry_strerror(ret));
 			break;
+		}
 
 		buf += s;
 	}
-	if (!ret)
-		ret = gcry_ac_key_init(&rsa_priv, rsa_hd,
-					GCRY_AC_KEY_SECRET, rsa_data_set);
-	if (ret)
-		goto Destroy_data_set;
 
-	ret = gcry_ac_data_new(&key_set);
-	if (ret)
-		goto Destroy_key;
+	/* setup private key */
+	if (!ret) {
+		ret = gcry_sexp_build(&rsa_priv, NULL,
+			"(private-key (rsa "
+			"(%s %m) (%s %m) (%s %m) (%s %m) (%s %m) (%s %m)"
+			"))",
+			rsa->field[0], mpi[0],
+			rsa->field[1], mpi[1],
+			rsa->field[2], mpi[2],
+			rsa->field[3], mpi[3],
+			rsa->field[4], mpi[4],
+			rsa->field[5], mpi[5]
+		);
+		if (ret) {
+			fprintf(stderr, "Failed to setup private key: %s\n", gcry_strerror(ret));
+		}
+	}
+	// Cleanup mpi's
+	// mi=RSA_FIELDS on normal exit, idx_broken on failure
+	for (j = mi-1; j >= 0; j--)
+		gcry_mpi_release(mpi[j]);
+	if (ret) {
+		fprintf(stderr, "Failed to setup private key: %s\n", gcry_strerror(ret));
+		goto Close_cypher;
+	}
 
-	gcry_mpi_scan(&mpi, GCRYMPI_FMT_USG, header->key.data,
+	ret = gcry_mpi_scan(&mpi[0], GCRYMPI_FMT_USG, header->key.data,
 			header->key.size, NULL);
-	ret = gcry_ac_data_set(key_set, GCRY_AC_FLAG_COPY, "a", mpi);
-	if (ret)
-		goto Destroy_key_set;
-
-	gcry_mpi_release(mpi);
-	ret = gcry_ac_data_decrypt(rsa_hd, 0, rsa_priv, &mpi, key_set);
-	if (!ret) {
-		unsigned char *res;
-		size_t s;
+	if (ret) {
+		fprintf(stderr, "Failed to read encrypted header: %s\n", gcry_strerror(ret));
+		goto Destroy_priv;
+	}
 
-		gcry_mpi_aprint(GCRYMPI_FMT_USG, &res, &s, mpi);
-		if (s == KEY_SIZE + CIPHER_BLOCK) {
-			memcpy(key, res, KEY_SIZE);
-			memcpy(ivec, res + KEY_SIZE, CIPHER_BLOCK);
-		} else {
-			ret = -ENODATA;
-		}
-		gcry_free(res);
+	/* setup cipher S-expr */
+	ret = gcry_sexp_build(&rsa_ciph, NULL,
+		"(enc-val (flags) (rsa (a %m)))", mpi[0]);
+	gcry_mpi_release(mpi[0]);
+	if (ret) {
+		fprintf(stderr, "Failed to setup cipher: %s\n", gcry_strerror(ret));
+		goto Destroy_priv;
 	}
 
-Destroy_key_set:
-	gcry_mpi_release(mpi);
-	gcry_ac_data_destroy(key_set);
+	/* decrypt the main key */
+	ret = gcry_pk_decrypt(&rsa_plain, rsa_ciph, rsa_priv);
+	if (ret) {
+		fprintf(stderr, "Can't decrypt the main key: %s\n", gcry_strerror(ret));
+		goto Destroy_ciph;
+	}
+	// retrieve decrypted mpi (value %m)
+	mpi[0] = gcry_sexp_nth_mpi(rsa_plain, 1, GCRYMPI_FMT_USG);
+	if (!mpi) {
+		fputs("Can't parse the main key", stderr);
+		ret = -EINVAL;
+		goto Destroy_plain;
+	}
 
-Destroy_key:
-	gcry_ac_key_destroy(rsa_priv);
+	unsigned char *res;
+	size_t s;
 
-Destroy_data_set:
-	gcry_ac_data_destroy(rsa_data_set);
+	gcry_mpi_aprint(GCRYMPI_FMT_USG, &res, &s, mpi[0]);
+	gcry_mpi_release(mpi[0]);
 
+	if (s == KEY_SIZE + CIPHER_BLOCK) {
+		memcpy(key, res, KEY_SIZE);
+		memcpy(ivec, res + KEY_SIZE, CIPHER_BLOCK);
+	} else {
+		fprintf(stderr,"The main key has invalid length %zi, need %zi\n", s, KEY_SIZE + CIPHER_BLOCK);
+		ret = -ENODATA;
+	}
+	gcry_free(res);
+
+Destroy_plain:
+	gcry_sexp_release(rsa_plain);
+Destroy_ciph:
+	gcry_sexp_release(rsa_ciph);
+Destroy_priv:
+	gcry_sexp_release(rsa_priv);
 Close_cypher:
 	gcry_cipher_close(sym_hd);
-
 Free_buffers:
 	freemem(out);
 	freemem(ivec_buf);
 	freemem(key_buf);
 
-Free_rsa:
-	gcry_ac_close(rsa_hd);
-
 	return ret;
 }
 
 static int restore_key(struct image_header_info *header)
 {
 	static unsigned char key[KEY_SIZE], ivec[CIPHER_BLOCK];
-	int error;
+	int error = 0;
 
 	if (header->flags & IMAGE_USE_RSA) {
 		error = decrypt_key(header, key, ivec);
@@ -569,11 +602,11 @@ static int restore_key(struct image_header_info *header)
 #endif
 
 int read_or_verify(int dev, int fd, struct image_header_info *header,
-                   loff_t start, int verify, int test)
+				   loff_t start, int verify, int test)
 {
 	static struct swap_reader handle;
 	static unsigned char orig_checksum[16], checksum[16];
-	static char csum_buf[48];
+	static char csum_buf[49];
 	int error = 0, test_mode = (verify || test);
 
 	error = read_page(fd, header, start);
diff --git a/resume.c b/resume.c
index a8685f2..dab2d26 100644
--- a/resume.c
+++ b/resume.c
@@ -429,6 +429,8 @@ int main(int argc, char *argv[])
 	int n, error, orig_loglevel;
 	static struct swsusp_header swsusp_header;
 
+	char mess_buf[SPLASH_GENERIC_MESSAGE_SIZE];
+
 	my_name = basename(argv[0]);
 
 	error = get_config(argc, argv);
@@ -534,8 +536,10 @@ int main(int argc, char *argv[])
 		fprintf(stderr, "%s: Could not read the image\n", my_name);
 	} else if (freeze(dev)) {
 		error = errno;
-		reboot_question("Processes could not be frozen, "
-				"cannot continue resuming.\n");
+		snprintf(mess_buf, SPLASH_GENERIC_MESSAGE_SIZE, 
+		"Processes could not be frozen, cannot continue resuming.\n"
+		"Error %i: %s\n", error, strerror(error));
+		reboot_question(mess_buf);
 	}
 
 	if (reset_signature(resume_dev, &swsusp_header))
diff --git a/s2ram-x86.c b/s2ram-x86.c
index a091af5..72816b1 100644
--- a/s2ram-x86.c
+++ b/s2ram-x86.c
@@ -38,6 +38,10 @@ static int vbe_mode = -1, dmi_scanned;
 #define S2RAM_NOFB	126
 #define S2RAM_UNKNOWN	127
 
+/* From s2ram-x86.h to avoid double definitions with no common block */
+char bios_version[ITEMSZ], sys_vendor[ITEMSZ], sys_product[ITEMSZ], sys_version[ITEMSZ];
+int flags, force, fb_nosuspend, no_kms_flag;
+
 void identify_machine(void)
 {
 	if (!dmi_scanned) {
diff --git a/s2ram-x86.h b/s2ram-x86.h
index 7149100..18845a5 100644
--- a/s2ram-x86.h
+++ b/s2ram-x86.h
@@ -18,9 +18,9 @@
 /* Item size */
 #define ITEMSZ  1024
 
-char bios_version[ITEMSZ], sys_vendor[ITEMSZ], sys_product[ITEMSZ], sys_version[ITEMSZ];
+extern char bios_version[ITEMSZ], sys_vendor[ITEMSZ], sys_product[ITEMSZ], sys_version[ITEMSZ];
 
-int flags, force, fb_nosuspend, no_kms_flag;
+extern int flags, force, fb_nosuspend, no_kms_flag;
 
 #define HACKS_LONG_OPTS \
 	{\
diff --git a/suspend.c b/suspend.c
index 479ce58..eb83a34 100644
--- a/suspend.c
+++ b/suspend.c
@@ -1959,15 +1959,13 @@ static inline void close_swappiness(void)
 #ifdef CONFIG_ENCRYPT
 static void generate_key(void)
 {
-	gcry_ac_handle_t rsa_hd;
-	gcry_ac_data_t rsa_data_set, key_set;
-	gcry_ac_key_t rsa_pub;
-	gcry_mpi_t mpi;
+	gcry_sexp_t rsa_pub, rsa_ciph, rsa_plain, rsa_mpi;
+	gcry_mpi_t mpi[RSA_FIELDS_PUB];
 	size_t size;
 	int ret, fd, rnd_fd;
 	struct RSA_data *rsa;
 	unsigned char *buf;
-	int j;
+	int mi;
 
 	fd = open(key_name, O_RDONLY);
 	if (fd < 0)
@@ -1977,41 +1975,41 @@ static void generate_key(void)
 	if (read(fd, rsa, sizeof(struct RSA_data)) <= 0)
 		goto Close;
 
-	ret = gcry_ac_open(&rsa_hd, GCRY_AC_RSA, 0);
-	if (ret)
-		goto Close;
-
 	buf = rsa->data;
-	ret = gcry_ac_data_new(&rsa_data_set);
-	if (ret)
-		goto Free_rsa;
+	for (mi = 0; mi < RSA_FIELDS_PUB; mi++) {
+		size_t s = rsa->size[mi];
 
-	for (j = 0; j < RSA_FIELDS_PUB; j++) {
-		size_t s = rsa->size[j];
-
-		gcry_mpi_scan(&mpi, GCRYMPI_FMT_USG, buf, s, NULL);
-		ret = gcry_ac_data_set(rsa_data_set, GCRY_AC_FLAG_COPY,
-					rsa->field[j], mpi);
-		gcry_mpi_release(mpi);
+		ret = gcry_mpi_scan(&mpi[mi], GCRYMPI_FMT_USG, buf, s, NULL);
 		if (ret)
 			break;
 
 		buf += s;
 	}
-	if (!ret)
-		ret = gcry_ac_key_init(&rsa_pub, rsa_hd, GCRY_AC_KEY_PUBLIC,
-					rsa_data_set);
-
-	if (ret)
-		goto Destroy_data_set;
+	if (ret) {
+		if (mi)
+			gcry_mpi_release(mpi[0]);
+		fprintf(stderr, "Failed to read mpi[%i] from RSA key: %s\n", mi, gcry_strerror(ret));
+		goto Close;
+	}
 
-	ret = gcry_ac_data_new(&key_set);
-	if (ret)
-		goto Destroy_key;
+	/* setup public key */
+	ret = gcry_sexp_build(&rsa_pub, NULL,
+		"(public-key (rsa"
+		"(%s %m) (%s %m)"
+		"))",
+		rsa->field[0], mpi[0],
+		rsa->field[1], mpi[1]
+	);
+	gcry_mpi_release(mpi[0]);
+	gcry_mpi_release(mpi[1]);
+	if (ret) {
+		fprintf(stderr, "Failed to setup RSA public key: %s\n", gcry_strerror(ret));
+		goto Close;
+	}
 
 	rnd_fd = open("/dev/urandom", O_RDONLY);
 	if (rnd_fd <= 0)
-		goto Destroy_key_set;
+		goto Destroy_pub;
 
 	size = KEY_SIZE + CIPHER_BLOCK;
 	for (;;) {
@@ -2022,48 +2020,73 @@ static void generate_key(void)
 		if (read(rnd_fd, key_data.key, size) != size)
 			goto Close_urandom;
 
-		gcry_mpi_scan(&mpi, GCRYMPI_FMT_USG, key_data.key, size, NULL);
-		gcry_mpi_aprint(GCRYMPI_FMT_USG, &res, &test, mpi);
+		ret = gcry_mpi_scan(&mpi[0], GCRYMPI_FMT_USG, key_data.key, size, NULL);
+		if (ret)
+			continue;
+		ret = gcry_mpi_aprint(GCRYMPI_FMT_USG, &res, &test, mpi[0]);
+		if (ret)
+			continue;
 		cmp = memcmp(key_data.key, res, size);
 		gcry_free(res);
 		if (test == size && !cmp)
 			break;
-		gcry_mpi_release(mpi);
-	}
-	ret = gcry_ac_data_encrypt(rsa_hd, 0, rsa_pub, mpi, &key_set);
-	gcry_mpi_release(mpi);
-	if (!ret) {
-		struct encrypted_key *key = &key_data.encrypted_key;
-		char *str;
-		size_t s;
-
-		gcry_ac_data_get_index(key_set, GCRY_AC_FLAG_COPY, 0,
-						(const char **)&str, &mpi);
-		gcry_free(str);
-		ret = gcry_mpi_print(GCRYMPI_FMT_USG, key->data, KEY_DATA_SIZE,
-					&s, mpi);
-		gcry_mpi_release(mpi);
-		if (!ret) {
-			key->size = s;
-			use_RSA = 'y';
-		}
+		gcry_mpi_release(mpi[0]);
 	}
 
-Close_urandom:
-	close(rnd_fd);
-
-Destroy_key_set:
-	gcry_ac_data_destroy(key_set);
+	/* setup plain text */
+	ret = gcry_sexp_build(&rsa_plain, NULL,
+		"(data (flags raw) (value %m))", mpi[0]);
+	gcry_mpi_release(mpi[0]);
+	if (ret) {
+		fprintf(stderr, "Failed to setup plain text: %s\n", gcry_strerror(ret));
+		goto Close_urandom;
+	}
 
-Destroy_key:
-	gcry_ac_key_destroy(rsa_pub);
+	/* encrypt the main key */
+	ret = gcry_pk_encrypt(&rsa_ciph, rsa_plain, rsa_pub);
+	if (ret) {
+		fprintf(stderr, "Failed to encrypt the main key: %s\n", gcry_strerror(ret));
+		goto Destroy_plain;
+	}
+	// retrieve a-value from S-expr (enc-val (rsa (a %m)))
+	rsa_mpi = gcry_sexp_find_token(rsa_ciph, "a", 0);
+	if (!rsa_mpi) {
+		fputs("Can't find encrypted RSA S-token", stderr);
+		ret = -EINVAL;
+		goto Destroy_ciph;
+	}
+	// retrieve encrypted mpi (enc-val (rsa (a %m)))
+	mpi[0] = gcry_sexp_nth_mpi(rsa_mpi, 1, GCRYMPI_FMT_USG);
+	if (!mpi[0]) {
+		fputs("Can't parse encrypted RSA S-token", stderr);
+		ret = -EINVAL;
+		goto Destroy_mpi;
+	}
 
-Destroy_data_set:
-	gcry_ac_data_destroy(rsa_data_set);
+	struct encrypted_key *key = &key_data.encrypted_key;
+	size_t s;
 
-Free_rsa:
-	gcry_ac_close(rsa_hd);
+	ret = gcry_mpi_print(GCRYMPI_FMT_USG, key->data, KEY_DATA_SIZE,
+				&s, mpi[0]);
+	if (!ret) {
+		key->size = s;
+		use_RSA = 'y';
+	} else {
+		fputs("Can't parse encrypted RSA MPI", stderr);
+		ret = -EINVAL;
+	}
 
+	gcry_mpi_release(mpi[0]);
+Destroy_mpi:
+	gcry_sexp_release(rsa_mpi);
+Destroy_ciph:
+	gcry_sexp_release(rsa_ciph);
+Destroy_plain:
+	gcry_sexp_release(rsa_plain);
+Close_urandom:
+	close(rnd_fd);
+Destroy_pub:
+	gcry_sexp_release(rsa_pub);
 Close:
 	close(fd);
 }
diff --git a/swsusp.h b/swsusp.h
index 2aae184..5f89902 100644
--- a/swsusp.h
+++ b/swsusp.h
@@ -12,6 +12,7 @@
 #include <stdint.h>
 #include <linux/fs.h>
 #include <linux/suspend_ioctls.h>
+#include <errno.h>
 
 #include "encrypt.h"
 
diff --git a/vbetool/vbetool.c b/vbetool/vbetool.c
index 55e019f..c5819b3 100644
--- a/vbetool/vbetool.c
+++ b/vbetool/vbetool.c
@@ -320,7 +320,7 @@ char *__save_state(int *psize)
 
 	memset(&r, 0, sizeof(r));
 
-	fprintf(stderr, "Allocated buffer at %p (base is 0x%x)\n", buffer,
+	fprintf(stderr, "Allocated buffer at %p (base is 0x%zx)\n", buffer,
 			LRMI_base_addr());
 
 	r.eax = 0x4f04;
diff --git a/wlcsv2c.pl b/wlcsv2c.pl
index 4c5555b..a744de8 100644
--- a/wlcsv2c.pl
+++ b/wlcsv2c.pl
@@ -2,21 +2,21 @@
 # Rodolfo Garcia kix_at_kix.es
 # suspend database management v1.0
 
-use Switch;
+use feature qw(switch);
 
-switch ($#ARGV) {
-  case 0 {
+given ($#ARGV) {
+  when(0) {
     my $fin = $ARGV[0];
     open(INF, "<$fin") or die "Could not open input file\n";
     open(OUF, ">&STDOUT") or die "Could not open output file\n";
   }
-  case 1 {
+  when(1) {
     my $fin = $ARGV[0];
     my $fout = $ARGV[1];
     open(INF, "<$fin") or die "Could not open input file\n";
     open(OUF, ">$fout") or die "Could not open output file\n";
   }
-  else {
+  default {
     my $msg = $0 . " <input-file> [output-file]";
     die $msg;
   }
