<commit_before>/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

/*
 * Implementation of the RW firmware signature verification and jump.
 */

#include "console.h"
#include "ec_commands.h"
#include "flash.h"
#include "host_command.h"
#include "rollback.h"
#include "rsa.h"
#include "rwsig.h"
#include "sha256.h"
#include "shared_mem.h"
#include "system.h"
#include "task.h"
#include "usb_pd.h"
#include "util.h"
#include "vb21_struct.h"
#include "version.h"

/* Console output macros */
#define CPRINTF(format, args...) cprintf(CC_SYSTEM, format, ## args)
#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ## args)

/* RW firmware reset vector */
static uint32_t * const rw_rst =
	(uint32_t *)(CONFIG_PROGRAM_MEMORY_BASE + CONFIG_RW_MEM_OFF + 4);


void rwsig_jump_now(void)
{
	/* Protect all flash before jumping to RW. */

	/*
	 * This may do nothing if WP is not enabled, RO is not
	 * protected, or if ALL_AT_BOOT is already set.
	 */
	flash_set_protect(EC_FLASH_PROTECT_ALL_AT_BOOT, -1);

	if (!(flash_get_protect() & EC_FLASH_PROTECT_ALL_NOW) &&
	      flash_get_protect() & EC_FLASH_PROTECT_ALL_AT_BOOT) {
		/*
		 * If flash protection is still not enabled (some chips may
		 * be able to enable it immediately), reboot.
		 */
		cflush();
		system_reset(SYSTEM_RESET_HARD | SYSTEM_RESET_PRESERVE_FLAGS);
	}

	/* When system is locked, only boot to RW is all flash is protected. */
	if (!system_is_locked() ||
	    flash_get_protect() & EC_FLASH_PROTECT_ALL_NOW)
		system_run_image_copy(SYSTEM_IMAGE_RW);
}

/*
 * Check that memory between rwdata[start] and rwdata[len-1] is filled
 * with ones. data, start and len must be aligned on 4-byte boundary.
 */
static int check_padding(const uint8_t *data,
			 unsigned int start, unsigned int len)
{
	unsigned int i;
	const uint32_t *data32 = (const uint32_t *)data;

	if ((start % 4) != 0 || (len % 4) != 0)
		return 0;

	for (i = start/4; i < len/4; i++) {
		if (data32[i] != 0xffffffff)
			return 0;<commit_msg>rwsig: protect flash with EC_FLASH_PROTECT_ALL_NOW whenever possible<commit_after>/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

/*
 * Implementation of the RW firmware signature verification and jump.
 */

#include "console.h"
#include "ec_commands.h"
#include "flash.h"
#include "host_command.h"
#include "rollback.h"
#include "rsa.h"
#include "rwsig.h"
#include "sha256.h"
#include "shared_mem.h"
#include "system.h"
#include "task.h"
#include "usb_pd.h"
#include "util.h"
#include "vb21_struct.h"
#include "version.h"

/* Console output macros */
#define CPRINTF(format, args...) cprintf(CC_SYSTEM, format, ## args)
#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ## args)

/* RW firmware reset vector */
static uint32_t * const rw_rst =
	(uint32_t *)(CONFIG_PROGRAM_MEMORY_BASE + CONFIG_RW_MEM_OFF + 4);


void rwsig_jump_now(void)
{
	/* Protect all flash before jumping to RW. */

	/* This may do nothing if WP is not enabled, RO is not protected. */
	flash_set_protect(EC_FLASH_PROTECT_ALL_NOW, -1);

	/*
	 * For chips that does not support EC_FLASH_PROTECT_ALL_NOW, use
	 * EC_FLASH_PROTECT_ALL_AT_BOOT.
	 */
	if (system_is_locked() &&
	    !(flash_get_protect() & EC_FLASH_PROTECT_ALL_NOW)) {
		flash_set_protect(EC_FLASH_PROTECT_ALL_AT_BOOT, -1);

		if (!(flash_get_protect() & EC_FLASH_PROTECT_ALL_NOW) &&
		    flash_get_protect() & EC_FLASH_PROTECT_ALL_AT_BOOT) {
			/*
			 * If flash protection is still not enabled (some chips
			 * may be able to enable it immediately), reboot.
			 */
			cflush();
			system_reset(SYSTEM_RESET_HARD |
				     SYSTEM_RESET_PRESERVE_FLAGS);
		}
	}

	/* When system is locked, only boot to RW if all flash is protected. */
	if (!system_is_locked() ||
	    flash_get_protect() & EC_FLASH_PROTECT_ALL_NOW)
		system_run_image_copy(SYSTEM_IMAGE_RW);
}

/*
 * Check that memory between rwdata[start] and rwdata[len-1] is filled
 * with ones. data, start and len must be aligned on 4-byte boundary.
 */
static int check_padding(const uint8_t *data,
			 unsigned int start, unsigned int len)
{
	unsigned int i;
	const uint32_t *data32 = (const uint32_t *)data;

	if ((start % 4) != 0 || (len % 4) != 0)
		return 0;

	for (i = start/4; i < len/4; i++) {
		if (data32[i] != 0xffffffff)
			return 0;
{'fraction_non_alphanumeric': 0.12159750111557341, 'fraction_numerical': 0.015841142347166444, 'mean_word_length': 4.077010192525481, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7410502', 'n_tokens_mistral': 1761, 'n_tokens_neox': 1586, 'n_words': 474}