/*
 * Copyright 2012 <James.Bottomley@HansenPartnership.com>
 *
 * see COPYING file
 *
 * Tool for manipulating system keys in setup mode
 */
#include <efi.h>
#include <efilib.h>
#include <console.h>

#include <simple_file.h>
#include <variables.h>
#include <guid.h>
#include <x509.h>
#include <efiauthenticated.h>

static EFI_HANDLE im;
static UINT8 SetupMode, SecureBoot, display_dbt;

#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))

enum {
	KEY_PK = 0,
	KEY_KEK,
	KEY_DB,
	KEY_DBX,
	KEY_DBT,
	KEY_MOK,
	MAX_KEYS
};

static struct {
	CHAR16 *name;
	CHAR16 *text;
	EFI_GUID *guid;
	int authenticated:1;
	int hash:1;
} keyinfo[] = {
	[KEY_PK] = {
		.name = L"PK",
		.text = L"The Platform Key (PK)",
		.guid = &GV_GUID,
		.authenticated = 1,
		.hash = 0,
	},
	[KEY_KEK] = {
		.name = L"KEK",
		.text = L"The Key Exchange Key Database (KEK)",
		.guid = &GV_GUID,
		.authenticated = 1,
		.hash = 0,
	},
	[KEY_DB] = {
		.name = L"db",
		.text = L"The Allowed Signatures Database (db)",
		.guid = &SIG_DB,
		.authenticated = 1,
		.hash = 1,
	},
	[KEY_DBX] = {
		.name = L"dbx",
		.text = L"The Forbidden Signatures Database (dbx)",
		.guid = &SIG_DB,
		.authenticated = 1,
		.hash = 1,
	},
	[KEY_DBT] = {
		.name = L"dbt",
		.text = L"The Timestamp Signatures Database (dbt)",
		.guid = &SIG_DB,
		.authenticated = 1,
		.hash = 0,
	},
	[KEY_MOK] = {
		.name = L"MokList",
		.text = L"The Machine Owner Key List (MokList)",
		.guid = &MOK_OWNER,
		.authenticated = 0,
		.hash = 1,
	}
};
static const int keyinfo_size = ARRAY_SIZE(keyinfo);

struct {
	EFI_GUID *guid;
	CHAR16 *name;
} signatures[] = {
	{ .guid = &X509_GUID,
	  .name = L"X509",
	},
	{ .guid = &RSA2048_GUID,
	  .name = L"RSA2048",
	},
	{ .guid = &EFI_CERT_SHA256_GUID,
	  .name = L"SHA256 signature",
	},
	{ .guid = &EFI_CERT_X509_SHA256_GUID,
	  .name = L"X509 SHA256 signature",
	},
	{ .guid = &EFI_CERT_X509_SHA384_GUID,
	  .name = L"X509 SHA384 signature",
	},
	{ .guid = &EFI_CERT_X509_SHA384_GUID,
	  .name = L"X509 SHA256 signature",
	},
};
static const int signatures_size = ARRAY_SIZE(signatures);

static void
select_and_apply(CHAR16 **title, CHAR16 *ext, int key, UINTN options)
{
	CHAR16 *file_name;
	EFI_STATUS status;
	EFI_FILE *file;
	EFI_HANDLE h = NULL;
	int use_setsecurevariable = 0;

	simple_file_selector(&h, title, L"\\", ext, &file_name);
	if (file_name == NULL)
		return;

	status = simple_file_open(h, file_name, &file, EFI_FILE_MODE_READ);
	if (status != EFI_SUCCESS)
		return;

	UINTN size;
	void *esl;
	simple_file_read_all(file, &size, &esl);
	simple_file_close(file);

	/* PK is different: need to update with an authenticated bundle
	 * including a signature with the new PK */
	if (StrCmp(&file_name[StrLen(file_name) - 4], L".esl") == 0) {
		if (keyinfo[key].authenticated)
			use_setsecurevariable = 1;
		else
			use_setsecurevariable = 0;
	} else if (StrCmp(&file_name[StrLen(file_name) - 5], L".auth") == 0) {
		use_setsecurevariable = 0;
		options |= EFI_VARIABLE_RUNTIME_ACCESS
			| EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
; 

		if (!keyinfo[key].authenticated) {
			console_errorbox(L"Can't set MOK variables with a .auth file");
			return;
		}
	} else {
		if (keyinfo[key].authenticated)
			use_setsecurevariable = 1;
		else
			use_setsecurevariable = 0;
		void *newesl;
		int newsize;

		status = variable_create_esl(esl, size, &X509_GUID, NULL,
					     &newesl, &newsize);

		if (status != EFI_SUCCESS) {
			console_error(L"Failed to create proper ESL", status);
			return;
		}
		FreePool(esl);
		esl = newesl;
		size = newsize;
	}
	if (use_setsecurevariable) {
		status = SetSecureVariable(keyinfo[key].name, esl, size,
					   *keyinfo[key].guid, options, 0);
	} else {
	  status = RT->SetVariable(keyinfo[key].name, keyinfo[key].guid,
				   EFI_VARIABLE_NON_VOLATILE
				   | EFI_VARIABLE_BOOTSERVICE_ACCESS
				   | options,
				   size, esl);
	}
	if (status != EFI_SUCCESS) {
		console_error(L"Failed to update variable", status);
		return;
	}
}

static int
StringSplit(CHAR16 *str, int maxlen, CHAR16 c, CHAR16 **out)
{
	int len = StrLen(str);
	int count = 0;

	if (len < maxlen) {
		out[0] = str;
		return 1;
	}
	while (len > 0) {
		int i, found = 0;

		for (i = 0; i < maxlen; i++) {
			if (str[i] == c)
				found = i;
			if (str[i] == '\0') {
				found = i;
				break;
			}
		}
		out[count++] = str;
		str[found] = '\0';
		str = str + found + 1;
		len -= found + 1;
	}
	return count;
}

static void
delete_key(int key, void *Data, int DataSize, EFI_SIGNATURE_LIST *CertList,
	   EFI_SIGNATURE_DATA *Cert)
{
	EFI_STATUS status;
	int certs = (CertList->SignatureListSize - sizeof(EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;

	if (certs == 1) {
		/* delete entire sig list + data */
		DataSize -= CertList->SignatureListSize;
		if (DataSize > 0)
			CopyMem(CertList,  (void *) CertList + CertList->SignatureListSize, DataSize - ((void *) CertList - Data));
	} else {
		int remain = DataSize - ((void *)Cert - Data) - CertList->SignatureSize;
		/* only delete single sig */
		DataSize -= CertList->SignatureSize;
		CertList->SignatureListSize -= CertList->SignatureSize;
		if (remain > 0)
			CopyMem(Cert, (void *)Cert + CertList->SignatureSize, remain);
	}

	if (keyinfo[key].authenticated)
		status = SetSecureVariable(keyinfo[key].name, Data,
					   DataSize,
					   *keyinfo[key].guid, 0, 0);
	else
		status = RT->SetVariable(keyinfo[key].name, keyinfo[key].guid,
					 EFI_VARIABLE_NON_VOLATILE
					 | EFI_VARIABLE_BOOTSERVICE_ACCESS,
					 DataSize, Data);

	if (status != EFI_SUCCESS)
		console_error(L"Failed to delete key", status);
}

static void
show_key(int key, int offset, void *Data, int DataSize)
{
	EFI_SIGNATURE_LIST *CertList;
	EFI_SIGNATURE_DATA *Cert = NULL;
	int cert_count = 0, i, Size, option = 0;
	CHAR16 *title[20], *options[4];
	CHAR16 str[256], str1[256], str2[256];

	title[0] = keyinfo[key].text;

	certlist_for_each_certentry(CertList, Data, Size, DataSize) {
		certentry_for_each_cert(Cert, CertList)
			if (cert_count++ == offset)
				goto finished;
	}
 finished:

	SPrint(str, sizeof(str), L"Sig[%d] - owner: %g", offset, &Cert->SignatureOwner);

	int c = 0;
	title[c++] = str;
	title[c] = L"Unknown";
	
	for (i = 0; i < signatures_size; i++) {
		if (CompareGuid(signatures[i].guid, &CertList->SignatureType) == 0) {
			SPrint(str1, sizeof(str1), L"Type: %s", signatures[i].name);
			title[c] = str1;
			break;
		}
	}
	CHAR16 buf[1024], buf1[1024], *tmpbuf[10], *tmpbuf1[10];
	if (CompareGuid(&CertList->SignatureType, &EFI_CERT_SHA256_GUID) == 0) {
		StrCpy(str2, L"Hash: ");
		sha256_StrCat_hash(str2, Cert->SignatureData);
		title[++c] = str2;
	} else if (CompareGuid(&CertList->SignatureType, &X509_GUID) == 0) {

		x509_to_str(Cert->SignatureData,
			    CertList->SignatureSize,
			    X509_OBJ_SUBJECT, buf, sizeof(buf));

		title[++c] = L"";
		title[++c] = L"Subject:";


		int sp = StringSplit(buf, 70, ',', tmpbuf);

		for (i = 0; i < sp; i++)
			title[++c] = tmpbuf[i];

		x509_to_str(Cert->SignatureData,
			    CertList->SignatureSize,
			    X509_OBJ_ISSUER, buf1, sizeof(buf1));

		sp = StringSplit(buf1, 70, ',', tmpbuf1);
	
		title[++c] = L"Issuer:";
		for (i = 0; i < sp; i++)
			title[++c] = tmpbuf1[i];
	} else if (CompareGuid(&CertList->SignatureType, &EFI_CERT_X509_SHA256_GUID) == 0) {
		EFI_CERT_X509_SHA256 *tmp = (void *)Cert->SignatureData;
		StrCpy(str2, L"Hash: ");
		sha256_StrCat_hash(str2, Cert->SignatureData);
		title[++c] = str2;
		EFI_TIME timestamp = tmp->TimeOfRevocation;
		SPrint(buf, sizeof(buf),
		       L"Revocation Timestamp: %d-%d-%d %02d:%02d:%02d\n",
		       timestamp.Year, timestamp.Month, timestamp.Day,
		       timestamp.Hour, timestamp.Minute, timestamp.Second);
		title[++c] = buf;
	}
	title[++c] = NULL;

	int o = 0;
	int option_delete = NOSEL, option_delete_w_auth = NOSEL,
		option_save = NOSEL;

	if (variable_is_setupmode() || key == KEY_MOK) {
		option_delete = o;
		options[o++] = L"Delete";
	}
	option_save = o;
	options[o++] = L"Save to File";
	if (key == KEY_PK) {
		option_delete_w_auth = o;
		options[o++] = L"Delete with .auth File";
	}
	options[o++] = NULL;
	option = console_select(title, options, option);
	if (option == -1)
		return;
	if (option == option_delete) {
		delete_key(key, Data, DataSize, CertList, Cert);
	} else if (option == option_save) {
		CHAR16 *filename;
		EFI_FILE *file;
		EFI_STATUS status;
		EFI_HANDLE vol;
		CHAR16 *volname;

		simple_volume_selector((CHAR16 *[]) {
				L"Save Key",
				L"",
				L"Select a disk Volume to save the key file to",
				L"The Key file will be saved in the top level directory",
				L"",
				L"Note: For USB volumes, some UEFI implementations aren't",
				L"very good at hotplug, so you may have to boot with the USB",
				L"Key already plugged in to see the volume",
				NULL
			}, &volname, &vol);
		/* no selection or ESC pressed */
		if (!volname)
			return;
		FreePool(volname);

		filename = AllocatePool(1024);

		SPrint(filename, 0, L"%s-%d.esl", keyinfo[key].name, offset);
		status = simple_file_open(vol, filename, &file, EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE);
		if (status == EFI_SUCCESS) {
			status = simple_file_write_all(file, CertList->SignatureListSize, CertList);
			simple_file_close(file);
		}

		if (status != EFI_SUCCESS) {
			CHAR16 str[80];

			SPrint(str, sizeof(str), L"Failed to write %s", filename);
			console_error(str, status);
		} else {
			CHAR16 str1[80], str2[80], str3[80];
			
			SPrint(str1, sizeof(str1), L"Key %s[%d]", keyinfo[key].name, offset);
			SPrint(str2, sizeof(str2), L"With GUID: %g", &Cert->SignatureOwner);
			SPrint(str3, sizeof(str3), L"saved to %s", filename);

			console_alertbox((CHAR16 *[]) {
					L"Successfully Saved",
					L"",
					str1,
					str2,
					str3,
					NULL
				});
		}
		FreePool(filename);
	} else if (option == option_delete_w_auth) {
		title[0] = L"Select authority bundle to remove PK";
		title[1] = NULL;
		select_and_apply(title, L".auth", key, 0);
	}
}

static void
add_new_key(int key, UINTN options)
{
	CHAR16 *title[3];
	/* PK update must be signed: so require .auth file */
	CHAR16 *ext;

	if (key != KEY_PK && (variable_is_setupmode()
			      || keyinfo[key].authenticated == 0))
		ext = L".esl|.auth|.cer";
	else
		ext = L".auth";

	title[0] = L"Select File containing additional key for";
	title[1] = keyinfo[key].text;
	title[2] = NULL;
	
	select_and_apply(title, ext, key, options);
}

static void
enroll_hash(int key)
{
	EFI_STATUS efi_status;
	CHAR16 *file_name = NULL, *title[6], buf0[256], buf1[256], buf2[256];
	UINT8 hash[SHA256_DIGEST_SIZE];
	int i;
	EFI_HANDLE h = NULL;

	simple_file_selector(&h, (CHAR16 *[]){
			L"Select Binary",
			L"",
			L"The Selected Binary will have its hash Enrolled",
			L"This means it will Subsequently Boot with no prompting",
			L"Remember to make sure it is a genuine binary before Enrolling its hash",
			NULL
		}, L"\\", NULL, &file_name);

	if (!file_name)
		/* user pressed ESC */
		return;

	efi_status = sha256_get_pecoff_digest(h, file_name, hash);
	if (efi_status != EFI_SUCCESS) {
		console_error(L"Hash failed (is efi binary valid?)",
			      efi_status);
		return;
	}
	
	StrCpy(buf0, L"Enroll hash into ");
	StrCat(buf0, keyinfo[key].text);
	title[0] = buf0;
	title[1] = L"";
	StrCpy(buf1, L"File: ");
	StrCat(buf1, file_name);
	title[2] = buf1;
	StrCpy(buf2, L"Hash: ");
	sha256_StrCat_hash(buf2, hash);
	title[3] = buf2;
	title[4] = NULL;
	i = console_yes_no(title);
	if (i == 0)
		return;

	efi_status = variable_enroll_hash(keyinfo[key].name,
					  *keyinfo[key].guid, hash);	
	if (efi_status != EFI_SUCCESS && efi_status != EFI_ALREADY_STARTED) {
		console_error(L"Failed to add signature to db", efi_status);
		return;
	}
}

static void
save_key_internal(int key, EFI_HANDLE vol, CHAR16 *error)
{
	EFI_STATUS status;
	EFI_FILE *file;
	UINT8 *data;
	UINTN len;
	CHAR16 file_name[512];

	StrCpy(error, keyinfo[key].name);
	status = get_variable(keyinfo[key].name, &data, &len,
			      *keyinfo[key].guid);
	if (status != EFI_SUCCESS) {
		if (status == EFI_NOT_FOUND)
			StrCat(error, L": Variable has no entries");
		else
			SPrint(error, 1024, L"%s: Failed to get variable (Error: %d)",
			       error, status);
		return;
	}
	StrCpy(file_name, L"\\");
	StrCat(file_name, keyinfo[key].name);
	StrCat(file_name, L".esl");
	status = simple_file_open(vol, file_name, &file,
				  EFI_FILE_MODE_READ
				  | EFI_FILE_MODE_WRITE
				  | EFI_FILE_MODE_CREATE);
	if (status != EFI_SUCCESS) {
		SPrint(error, 1024, L"%s: Failed to open file %s (Error: %d)",
		       error, file_name, status);
		return;
	}
	status = simple_file_write_all(file, len, data);
	simple_file_close(file);
	if (status != EFI_SUCCESS) {
		SPrint(error, 1024, L"%s: Failed to write to %s (Error: %d)",
		       error, file_name, status);
		return;
	}
	StrCat(error, L": Successfully written to ");
	StrCat(error, file_name);
}

static void
save_key(int key)
{
	EFI_HANDLE vol;
	CHAR16 *volname;

	simple_volume_selector((CHAR16 *[]) {
			L"Save Key",
			L"",
			L"Select a disk Volume to save the key file to",
			L"The key file will be saved in the top level directory",
			L"",
			L"Note: For USB volumes, some UEFI implementations aren't",
			L"very good at hotplug, so you may have to boot with the USB",
			L"USB device already plugged in to see the volume",
			NULL
		}, &volname, &vol);
	/* no selection or ESC pressed */
	if (!volname)
		return;
	FreePool(volname);

	CHAR16 buf[1024], *title[2];

	save_key_internal(key, vol, buf);
	title[0] = buf;
	title[1] = NULL;

	console_alertbox(title);
}

static void
manipulate_key(int key)
{
	CHAR16 *title[5];
	EFI_STATUS efi_status;
	int setup_mode = variable_is_setupmode(), i;

	title[0] = L"Manipulating Contents of";
	title[1] = keyinfo[key].text;
	title[2] = NULL;

	UINT8 *Data;
	UINTN DataSize = 0, Size;
	efi_status = RT->GetVariable(keyinfo[key].name, keyinfo[key].guid, NULL, &DataSize, NULL);
	if (efi_status != EFI_BUFFER_TOO_SMALL && efi_status != EFI_NOT_FOUND) {
		console_error(L"Failed to get DataSize", efi_status);
		return;
	}

	Data = AllocatePool(DataSize);
	if (!Data) {
		CHAR16 str[80];
		SPrint(str, sizeof(str), L"Failed to allocate %d", DataSize);
		console_errorbox(str);
		return;
	}

	efi_status = RT->GetVariable(keyinfo[key].name, keyinfo[key].guid, NULL, &DataSize, Data);
	if (efi_status == EFI_NOT_FOUND) {
		int t = 2;
		title[t++] = L"Variable is Empty";
		if (key == KEY_PK)
			title[t++] = L"WARNING: Setting PK will take the platform out of Setup Mode";
		title[t++] = NULL;
	} else if (efi_status != EFI_SUCCESS) {
		console_error(L"Failed to get variable", efi_status);
		return;
	}

	EFI_SIGNATURE_LIST *CertList;
	int cert_count = 0, add = NOSEL, replace = NOSEL, hash = NOSEL,
		save = NOSEL;
	certlist_for_each_certentry(CertList, Data, Size, DataSize) {
		cert_count += (CertList->SignatureListSize - sizeof(EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
	}

	CHAR16 **guids = (CHAR16 **)AllocatePool((cert_count + 5)*sizeof(void *));
	cert_count = 0;
	int g;
	certlist_for_each_certentry(CertList, Data, Size, DataSize) {
		EFI_SIGNATURE_DATA *Cert;

		certentry_for_each_cert(Cert, CertList) {
			guids[cert_count] = AllocatePool(64*sizeof(CHAR16));
			SPrint(guids[cert_count++], 64*sizeof(CHAR16), L"%g", &Cert->SignatureOwner);
		}
	}
	g = cert_count;
	if (key != 0) {
		add = g;
		guids[g++] = L"Add New Key";
	}
	replace = g;
	guids[g++] = L"Replace Key(s)";

	if (keyinfo[key].hash && (!keyinfo[key].authenticated || setup_mode)) {
		hash = g;
		guids[g++] = L"Enroll hash of binary";
	}

	if (cert_count != 0) {
		save = g;
		guids[g++] = L"Save key";
	}

	guids[g] = NULL;
	int select = console_select(title, guids, 0);
	for (i = 0; i < cert_count; i++)
		FreePool(guids[i]);
	FreePool(guids);
	if (select == replace)
		add_new_key(key, 0);
	else if (select == add)
		add_new_key(key, EFI_VARIABLE_APPEND_WRITE);
	else if (select == hash)
		enroll_hash(key);
	else if (select == save)
		save_key(key);
	else if (select >= 0)
		show_key(key, select, Data, DataSize);
	FreePool(Data);
}

static void
select_key(void)
{
	int i, j;
	int keymap[keyinfo_size + 1];
	CHAR16 *keys[keyinfo_size + 1];

	for (i = 0, j = 0; i < keyinfo_size; i++) {
		if (i == KEY_DBT && !display_dbt)
			continue;
		keys[j] = keyinfo[i].text;
		keymap[j++] = i;
	}
	keys[j] = NULL;

	i = 0;

	for (;;) {
		i = console_select( (CHAR16 *[]){ L"Select Key to Manipulate", NULL }, keys, i);
		if (i == -1)
			break;
		manipulate_key(keymap[i]);
	}
}

static void
save_keys(void)
{
	EFI_HANDLE vol;
	CHAR16 *volname;

	simple_volume_selector((CHAR16 *[]) {
			L"Save Keys",
			L"",
			L"Select a disk Volume to save all the key files to",
			L"Key files will be saved in the top level directory",
			L"",
			L"Note: For USB volumes, some UEFI implementations aren't",
			L"very good at hotplug, so you may have to boot with the USB",
			L"USB device already plugged in to see the volume",
			NULL
		}, &volname, &vol);
	/* no selection or ESC pressed */
	if (!volname)
		return;
	FreePool(volname);

	CHAR16 *title[10], buf[8000];
	int i, t_c = 0, b_c = 0;

	title[t_c++] = L"Results of Saving Keys";
	title[t_c++] = L"";

	for (i = 0; i < MAX_KEYS; i++) {
		if (i == KEY_DBT && !display_dbt)
			continue;
		save_key_internal(i, vol, &buf[b_c]);
		title[t_c++] = &buf[b_c];
		b_c += StrLen(&buf[b_c]) + 1;
	}
	title[t_c] = NULL;
	console_alertbox(title);
}

static void
execute_binary()
{
	CHAR16 *bin_name;
	EFI_HANDLE h = NULL;
	EFI_HANDLE ih;
	EFI_DEVICE_PATH *devpath;
	EFI_STATUS status;

	simple_file_selector(&h, (CHAR16 *[]) {
			L"Select Binary to Execute",
			L"",
			NULL
		}, L"\\",
		NULL, &bin_name);
	if (!bin_name) {
		/* user pressed ESC */
		return;
	}

	/* the execute() call is designed to construct handles from
	 * local resources on the image.  We have a handle and a full
	 * path name, so we follow proper process here */

	devpath = FileDevicePath(h, bin_name);

	status = BS->LoadImage(FALSE, im, devpath, NULL, 0, &ih);
	if (status != EFI_SUCCESS) {
		console_error(L"Image failed to load", status);
		return;
	}

	status = BS->StartImage(ih, NULL, NULL);
	BS->UnloadImage(ih);

	if (status != EFI_SUCCESS)
		console_error(L"Execution returned error", status);
}

EFI_STATUS
efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
{
	EFI_STATUS efi_status;
	UINTN DataSize = sizeof(SetupMode);
	int option = 0;

	im = image;

	InitializeLib(image, systab);

	if (GetOSIndications() & EFI_OS_INDICATIONS_TIMESTAMP_REVOCATION)
		display_dbt = 1;

	efi_status = RT->GetVariable(L"SetupMode", &GV_GUID, NULL, &DataSize, &SetupMode);

	if (efi_status != EFI_SUCCESS) {
		Print(L"No SetupMode variable ... is platform secure boot enabled?\n");		return EFI_SUCCESS;
	}

	for (;;) {

		CHAR16 line2[80], line3[80], **title;

		SetupMode = variable_is_setupmode();
		SecureBoot = variable_is_secureboot();

		line2[0] = line3[0] = L'\0';

		StrCat(line2, L"Platform is in ");
		StrCat(line2, SetupMode ? L"Setup Mode" : L"User Mode");
		StrCat(line3, L"Secure Boot is ");
		StrCat(line3, SecureBoot ? L"on" : L"off");
		title =  (CHAR16 *[]){L"KeyTool main menu", L"", line2, line3, NULL };

		option = console_select(title, (CHAR16 *[]){ 
				L"Save Keys",
				L"Edit Keys",
				L"Execute Binary",
				L"Exit",
				NULL },
			option);

		switch (option) {
		case 0:
			save_keys();
			break;
		case 1:
			select_key();
			break;
		case 2:
			execute_binary();
			break;
		case 3:
			/* exit from programme */
			return EFI_SUCCESS;
		default:
			break;
		}
	}

	return EFI_SUCCESS;
}
