/*
 * Copyright (c) 2019, Arm Limited. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <cdefs.h>
#include <stdint.h>

/*
 * Instruction pointer authentication key A. The low 64-bit are at [0], and the
 * high bits at [1].
 */
uint64_t plat_apiakey[2];

/*
 * This is only a toy implementation to generate a seemingly random 128-bit key
 * from sp and x30 values. A production system must re-implement this function
 * to generate keys from a reliable randomness source.
 */
uint64_t *plat_init_apiakey(void)
{
	uintptr_t return_addr = (uintptr_t)__builtin_return_address(0U);
	uintptr_t frame_addr = (uintptr_t)__builtin_frame_address(0U);

	plat_apiakey[0] = (return_addr << 13) ^ frame_addr;
	plat_apiakey[1] = (frame_addr << 15) ^ return_addr;

	return plat_apiakey;
}

/*
 * Copyright (c) 2019, Arm Limited. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <cdefs.h>
#include <stdint.h>

/*
 * Instruction pointer authentication key A. The low 64-bit are at [0], and the
 * high bits at [1]. They are run-time constants so they are placed in the
 * rodata section. They are written before MMU is turned on and the permissions
 * are effective.
 */
uint64_t plat_apiakey[2] __section("rodata.apiakey");

/*
 * This is only a toy implementation to generate a seemingly random 128-bit key
 * from sp and x30 values. A production system must re-implement this function
 * to generate keys from a reliable randomness source.
 */
uint64_t *plat_init_apiakey(void)
{
	uintptr_t return_addr = (uintptr_t)__builtin_return_address(0U);
	uintptr_t frame_addr = (uintptr_t)__builtin_frame_address(0U);

	plat_apiakey[0] = (return_addr << 13) ^ frame_addr;
	plat_apiakey[1] = (frame_addr << 15) ^ return_addr;

	return plat_apiakey;
}

--- 
+++ 
@@ -9,11 +9,9 @@
 
 /*
  * Instruction pointer authentication key A. The low 64-bit are at [0], and the
- * high bits at [1]. They are run-time constants so they are placed in the
- * rodata section. They are written before MMU is turned on and the permissions
- * are effective.
+ * high bits at [1].
  */
-uint64_t plat_apiakey[2] __section("rodata.apiakey");
+uint64_t plat_apiakey[2];
 
 /*
  * This is only a toy implementation to generate a seemingly random 128-bit key
Put Pointer Authentication key value in BSS section

The dummy implementation of the plat_init_apiakey() platform API uses
an internal 128-bit buffer to store the initial key value used for
Pointer Authentication support.

The intent - as stated in the file comments - was for this buffer to
be write-protected by the MMU. Initialization of the buffer would be
performed before enabling the MMU, thus bypassing write protection
checks.

However, the key buffer ended up into its own read-write section by
mistake due to a typo on the section name ('rodata.apiakey' instead of
'.rodata.apiakey', note the leading dot). As a result, the linker
script was not pulling it into the .rodata output section.

One way to address this issue could have been to fix the section
name. However, this approach does not work well for BL1. Being the
first image in the boot flow, it typically is sitting in real ROM
so we don't have the capacity to update the key buffer at any time.

The dummy implementation of plat_init_apiakey() provided at the moment
is just there to demonstrate the Pointer Authentication feature in
action. Proper key management and key generation would have to be a
lot more careful on a production system.

Therefore, the approach chosen here to leave the key buffer in
writable memory but move it to the BSS section. This does mean that
the key buffer could be maliciously updated for intalling unintended
keys on the warm boot path but at the feature is only at an
experimental stage right now, this is deemed acceptable.

Change-Id: I121ccf35fe7bc86c73275a4586b32d4bc14698d6
Signed-off-by: Sandrine Bailleux <4b69fcfca8da45b0c11ecda5434c5da526575d9d@arm.com>
