Exemplo n.º 1
0
/* some UEFI machines have a buggy implementation
 * see if we can tip the system into Setup Mode */
static EFI_STATUS
change_setup_mode(int user_mode)
{
	static UINT8 *data = NULL;
	static UINTN len = 0;
	EFI_STATUS status;

	if (user_mode) {
		if (!data)
			/* can only do this if we previously reset to setup */
			return EFI_INVALID_PARAMETER;

		status = SetSecureVariable(L"PK", data, len, GV_GUID, 0, 0);	

		if (status == EFI_SUCCESS) {
			data = NULL;
			len = 0;
		}
		return status;
		
	} else {
		status = get_variable(L"PK", &data, &len, GV_GUID);
		if (status != EFI_SUCCESS)
			return status;
		/* try to update it to nothing */
		return SetSecureVariable(L"PK", data, 0, GV_GUID, 0, 0);	
	}

}
Exemplo n.º 2
0
EFI_STATUS
variable_enroll_hash(CHAR16 *var, EFI_GUID owner,
		     UINT8 hash[SHA256_DIGEST_SIZE])
{
	EFI_STATUS status;

	if (find_in_variable_esl(var, owner, hash, SHA256_DIGEST_SIZE)
	    == EFI_SUCCESS)
		/* hash already present */
		return EFI_ALREADY_STARTED;

	UINT8 sig[sizeof(EFI_SIGNATURE_LIST) + sizeof(EFI_SIGNATURE_DATA) - 1 + SHA256_DIGEST_SIZE];
	EFI_SIGNATURE_LIST *l = (void *)sig;
	EFI_SIGNATURE_DATA *d = (void *)sig + sizeof(EFI_SIGNATURE_LIST);
	SetMem(sig, 0, sizeof(sig));
	l->SignatureType = EFI_CERT_SHA256_GUID;
	l->SignatureListSize = sizeof(sig);
	l->SignatureSize = 16 +32; /* UEFI defined */
	CopyMem(&d->SignatureData, hash, SHA256_DIGEST_SIZE);
	d->SignatureOwner = MOK_OWNER;

	if (CompareGuid(&owner, &SIG_DB) == 0)
		status = SetSecureVariable(var, sig, sizeof(sig), owner,
					   EFI_VARIABLE_APPEND_WRITE, 0);
	else
		status = uefi_call_wrapper(RT->SetVariable, 5, var, &owner,
					   EFI_VARIABLE_NON_VOLATILE
					   | EFI_VARIABLE_BOOTSERVICE_ACCESS
					   | EFI_VARIABLE_APPEND_WRITE,
					   sizeof(sig), sig);
	return status;
}
Exemplo n.º 3
0
EFI_STATUS
efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
{
	EFI_STATUS efi_status;
	UINT8 SecureBoot, SetupMode;
	UINTN DataSize = sizeof(SetupMode);

	InitializeLib(image, systab);

	efi_status = uefi_call_wrapper(RT->GetVariable, 5, 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;
	}

	if (!SetupMode) {
		Print(L"Platform is not in Setup Mode, cannot install Keys\n");
		return EFI_SUCCESS;
	}

	Print(L"Platform is in Setup Mode\n");

	efi_status = uefi_call_wrapper(RT->SetVariable, 5, L"KEK", &GV_GUID,
				       EFI_VARIABLE_NON_VOLATILE
				       | EFI_VARIABLE_RUNTIME_ACCESS 
				       | EFI_VARIABLE_BOOTSERVICE_ACCESS
				       | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS,
				       KEK_auth_len, KEK_auth);
	if (efi_status != EFI_SUCCESS) {
		Print(L"Failed to enroll KEK: %d\n", efi_status);
		return efi_status;
	}
	Print(L"Created KEK Cert\n");
	efi_status = uefi_call_wrapper(RT->SetVariable, 5, L"db", &SIG_DB,
				       EFI_VARIABLE_NON_VOLATILE
				       | EFI_VARIABLE_RUNTIME_ACCESS 
				       | EFI_VARIABLE_BOOTSERVICE_ACCESS
				       | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS,
				       DB_auth_len, DB_auth);
	if (efi_status != EFI_SUCCESS) {
		Print(L"Failed to enroll db: %d\n", efi_status);
		return efi_status;
	}
	Print(L"Created db Cert\n");
#if 0
	/* testing revocation ... this will revoke the certificate
	 * we just enrolled in db */
	efi_status = SetSecureVariable(L"dbx", DB_cer, DB_cer_len, SIG_DB, 0);
	if (efi_status != EFI_SUCCESS) {
		Print(L"Failed to enroll dbx: %d\n", efi_status);
		return efi_status;
	}
#endif
	/* PK must be updated with a signed copy of itself */
	efi_status = uefi_call_wrapper(RT->SetVariable, 5, L"PK", &GV_GUID,
				       EFI_VARIABLE_NON_VOLATILE
				       | EFI_VARIABLE_RUNTIME_ACCESS 
				       | EFI_VARIABLE_BOOTSERVICE_ACCESS
				       | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS,
				       PK_auth_len, PK_auth);

	
	if (efi_status != EFI_SUCCESS) {
		Print(L"Failed to enroll PK: %d\n", efi_status);
		return efi_status;
	}
	Print(L"Created PK Cert\n");
	/* enrolling the PK should put us in SetupMode; check this */
	efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"SetupMode", &GV_GUID, NULL, &DataSize, &SetupMode);
	if (efi_status != EFI_SUCCESS) {
		Print(L"Failed to get SetupMode variable: %d\n", efi_status);
		return efi_status;
	}
	Print(L"Platform is in %s Mode\n", SetupMode ? L"Setup" : L"User");

	/* finally, check that SecureBoot is enabled */

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

	if (efi_status != EFI_SUCCESS) {
		Print(L"Failed to get SecureBoot variable: %d\n", efi_status);
		return efi_status;
	}
	Print(L"Platform %s set to boot securely\n", SecureBoot ? L"is" : L"is not");

	return EFI_SUCCESS;
}
Exemplo n.º 4
0
EFI_STATUS
efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
{
	EFI_STATUS status;
	int argc, i, esl_mode = 0, hash_mode = 0;
	CHAR16 **ARGV, *var, *name, *progname, *owner_guid;
	EFI_FILE *file;
	void *buf;
	UINTN size, options = 0;
	EFI_GUID *owner;
	CHAR16 *variables[] = { L"PK", L"KEK", L"db", L"dbx", L"MokList" };
	EFI_GUID *owners[] = { &GV_GUID, &GV_GUID, &SIG_DB, &SIG_DB,
			       &MOK_OWNER };

	InitializeLib(image, systab);

	status = argsplit(image, &argc, &ARGV);

	if (status != EFI_SUCCESS) {
		Print(L"Failed to parse arguments: %d\n", status);
		return status;
	}

	progname = ARGV[0];
	while (argc > 1 && ARGV[1][0] == L'-') {
		if (StrCmp(ARGV[1], L"-a") == 0) {
			options |= EFI_VARIABLE_APPEND_WRITE;
			ARGV += 1;
			argc -= 1;
		} else if (StrCmp(ARGV[1], L"-g") == 0) {
			owner_guid = ARGV[2];
			ARGV += 2;
			argc -= 2;
		} else if (StrCmp(ARGV[1], L"-e") == 0) {
			esl_mode = 1;
			ARGV += 1;
			argc -= 1;
		} else if (StrCmp(ARGV[1], L"-b") == 0) {
			esl_mode = 1;
			hash_mode = 1;
			ARGV += 1;
			argc -= 1;
		} else {
			/* unrecognised option */
			break;
		}
	}

	if (argc != 3 ) {
		Print(L"Usage: %s: [-g guid] [-a] [-e] [-b] var file\n", progname);
		return EFI_INVALID_PARAMETER;
	}

	var = ARGV[1];
	name = ARGV[2];

	for(i = 0; i < ARRAY_SIZE(variables); i++) {
		if (StrCmp(var, variables[i]) == 0) {
			owner = owners[i];
			break;
		}
	}
	if (i == ARRAY_SIZE(variables)) {
		Print(L"Invalid Variable %s\nVariable must be one of: ", var);
		for (i = 0; i < ARRAY_SIZE(variables); i++)
			Print(L"%s ", variables[i]);
		Print(L"\n");
		return EFI_INVALID_PARAMETER;
	}

	if (owner == &MOK_OWNER) {
		if (!esl_mode) {
			Print(L"MoK variables can only be updated in ESL mode\n");
			return EFI_INVALID_PARAMETER;
		}
		/* hack: esl goes directly into MoK variables, so we now
		 * pretend we have a direct .auth update */
		esl_mode = 0;
	} else {
		/* non MoK variables have runtime access and time based
		 * authentication, MoK ones don't */
		options |= EFI_VARIABLE_RUNTIME_ACCESS
			| EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
	}
		

	status = simple_file_open(image, name, &file, EFI_FILE_MODE_READ);
	if (status != EFI_SUCCESS) {
		Print(L"Failed to open file %s\n", name);
		return status;
	}

	status = simple_file_read_all(file, &size, &buf);
	if (status != EFI_SUCCESS) {
		Print(L"Failed to read file %s\n", name);
		return status;
	}
	simple_file_close(file);

	if (hash_mode) {
		UINT8 hash[SHA256_DIGEST_SIZE];

		status = sha256_get_pecoff_digest_mem(buf, size, hash);
		if (status != EFI_SUCCESS) {
			Print(L"Failed to get hash of %s\n", name);
			return status;
		}
		status = variable_enroll_hash(var, *owner, hash);
	} else if (esl_mode) {
		status = SetSecureVariable(var, buf, size, *owner, options, 0);
	} else {
		status = uefi_call_wrapper(RT->SetVariable, 5, var, owner,
					   EFI_VARIABLE_NON_VOLATILE
					   | EFI_VARIABLE_BOOTSERVICE_ACCESS
					   | options,
					   size, buf);
	}

	if (status != EFI_SUCCESS) {
		Print(L"Failed to update variable %s: %d\n", var, status);
		return status;
	}
	return EFI_SUCCESS;
}