diff --git a/Makefile b/Makefile
index a79c6dd..67d1dac 100644
--- a/Makefile
+++ b/Makefile
@@ -81,7 +81,8 @@ STAGE1_NETWORK_LIBS = $($(L)_STAGE1_NETWORK_LIBS)
 STAGE1SRC = stage1.c log.c tools.c modules.c probing.c \
 	mount.c lomount.c automatic.c frontend-common.c \
 	cdrom.c disk.c common.c \
-	network.c dhcp.c url.c dns.c adsl.c
+	network.c dhcp.c url.c dns.c adsl.c \
+	sha256.c
 
 STAGE1OBJS = $(addprefix $(L)-,$(subst .c,.o,$(STAGE1SRC)))
 
diff --git a/cdrom.c b/cdrom.c
index b0924ea..f06368b 100644
--- a/cdrom.c
+++ b/cdrom.c
@@ -64,9 +64,10 @@ static int mount_that_cd_device(char * dev_name)
 	return mount_iso9660(device_fullname);
 }
 
-
-static int test_that_cd()
+/* test_that_cd() returns 0 on success */
+static int test_that_cd(int no_digest)
 {
+	if (IS_VERIFICATION && !no_digest) return !verify_ramdisk_digest(get_ramdisk_path(NULL), get_param_valued("hash"));
 	log_message("test file on cd: %s\n", get_ramdisk_path(NULL));
 	return access(get_ramdisk_path(NULL), R_OK);
 }
@@ -79,10 +80,14 @@ static enum return_type do_with_device(char * dev_name, char * dev_model)
 	struct stat st;
 	char msg[256];
 	char * ramdisk_path;
-	if (test_that_cd()) {
+	if (test_that_cd(0)) {
 		enum return_type results;
 		umount(IMAGE_LOCATION);
-		snprintf(msg, sizeof(msg), "That ISO does not seem like proper %s"
+		if (IS_VERIFICATION)
+			snprintf(msg, sizeof(msg), "That ISO (on %s) does not seem like proper %s"
+				 " media: hash verification failed.\nRetry with another one?", dev_name, version);
+		else
+			snprintf(msg, sizeof(msg), "That ISO does not seem like proper %s"
 				 " media.\nRetry with another one?", version);
 		results = ask_yes_no(msg);
 		if (results == RETURN_OK)
@@ -150,7 +155,7 @@ int try_automatic(char ** medias, char ** medias_models)
 
 		wait_message("Trying to access media in drive %s", *model);
 		if (mount_that_cd_device(*ptr) != -1) {
-			if (!test_that_cd()) {
+			if (!test_that_cd(1)) {
 				remove_wait_message();
 				return i;
 			}
diff --git a/stage1.h b/stage1.h
index c9875db..5bd5c60 100644
--- a/stage1.h
+++ b/stage1.h
@@ -43,6 +43,7 @@ extern char * interactive_fifo;
 #define MODE_CHANGEDISK     (1 << 10)
 #define MODE_UPDATEMODULES  (1 << 11)
 #define MODE_SPLASH  (1 << 12)
+#define MODE_VERIFICATION  (1 << 13)
 
 #define IS_TESTING     (get_param(MODE_TESTING))
 #define IS_EXPERT      (get_param(MODE_EXPERT))
@@ -56,6 +57,7 @@ extern char * interactive_fifo;
 #define IS_CHANGEDISK  (get_param(MODE_CHANGEDISK))
 #define IS_UPDATEMODULES (get_param(MODE_UPDATEMODULES))
 #define IS_SPLASH (get_param(MODE_SPLASH))
+#define IS_VERIFICATION (get_param(MODE_VERIFICATION))
 
 void fatal_error(char *msg) __attribute__ ((noreturn));
 
diff --git a/tools.c b/tools.c
index 674b777..c6e8790 100644
--- a/tools.c
+++ b/tools.c
@@ -42,6 +42,7 @@
 #include <linux/loop.h>
 #include "tools.h"
 #include "modules.h"
+#include "sha256.h"
 #ifdef SPAWN_SPLASH
 #include "init.h"
 #endif
@@ -98,6 +99,7 @@ void process_cmdline(void)
 		if (!strcmp(name, "live")) set_param(MODE_LIVE);
 		if (!strcmp(name, "stagename")) set_param(MODE_STAGENAME);
 		if (!strcmp(name, "lowmem")) set_param(MODE_LOWMEM);
+		if (!strcmp(name, "hash")) set_param(MODE_VERIFICATION);
 		if (!strcmp(name, "automatic")) {
 			set_param(MODE_AUTOMATIC);
 			grab_automatic_params(value);
@@ -352,6 +354,54 @@ char * get_ramdisk_path(const char *mount_path)
     return strdup(img_name);
 }
 
+/* This function is used to protect against stage2 (aka ramdisk) spoofing */
+int verify_ramdisk_digest(const char *filename, const char *sha256_hash)
+{
+	FILE *fp;
+	char buffer[8192];
+	size_t len;
+	sha256_context ctx;
+	uint8 digest[32];
+	char computed_hash[64];
+	char * wait_msg = "Verifying stage2 authenticity...";
+	struct stat st;
+	int bytes_read = 0;
+	int ramdisk_size;
+
+	if(sha256_hash == NULL) return 0;
+
+	if(stat(filename, &st)) return 0;
+	ramdisk_size = st.st_size;
+
+	fp = fopen(filename, "rb");
+	if(fp == NULL) return 0;
+
+	init_progression(wait_msg, ramdisk_size);
+	sha256_starts(&ctx);
+	while((len = fread(buffer, 1, sizeof(buffer), fp)) > 0)
+	{
+		if(ferror(fp))
+		{
+			fclose(fp);
+			log_message("error reading ramdisk");
+			remove_wait_message();
+			return 0;
+		}
+		sha256_update(&ctx, buffer, len);
+		update_progression((int)(bytes_read += len));
+	}
+	sha256_finish(&ctx, digest);
+	end_progression();
+
+	fclose(fp);
+
+	len = 0;
+	int i = 0;
+	for (i; i < 32; i++) len += sprintf(computed_hash + len, "%02x", digest[i]);
+
+	return (strcmp(computed_hash, sha256_hash) == 0);
+}
+
 enum return_type load_ramdisk(char *mount_path)
 {
 	int st2_fd;
diff --git a/tools.h b/tools.h
index 8545d46..469102f 100644
--- a/tools.h
+++ b/tools.h
@@ -43,6 +43,7 @@ char ** list_directory(char * direct);
 int string_array_length(char ** a);
 int do_losetup(char * device, char * target);
 char * get_ramdisk_path(const char *);
+int verify_ramdisk_digest(const char *filename, const char *sha256_hash);
 int splash_verbose();
 int update_splash(char * state);
 int prepare_progress(void);