[PATCH v4 1/3] net: add a generic udp protocol

2020-09-18 Thread Philippe Reynes
This commit adds a generic udp protocol framework in the
network loop. So protocol based on udp may be implemented
without modifying the network loop (for example custom
wait magic packet).

Signed-off-by: Philippe Reynes 
Reviewed-by: Simon Glass 
---

Changelog:
v4:
- no change

v3:
- add file doc/README.udp
- add more comments on function udp_loop
- fix sentence in Kconfig
- use if (IS_ENABLE(...)) when it is possible
- avoid checking null pointer twice

v2:
- no change

 doc/README.udp| 35 +++
 include/net.h |  2 +-
 include/net/udp.h | 41 +
 net/Kconfig   |  6 ++
 net/Makefile  |  1 +
 net/net.c | 13 -
 net/udp.c | 46 ++
 7 files changed, 142 insertions(+), 2 deletions(-)
 create mode 100644 doc/README.udp
 create mode 100644 include/net/udp.h
 create mode 100644 net/udp.c

diff --git a/doc/README.udp b/doc/README.udp
new file mode 100644
index 000..da07257
--- /dev/null
+++ b/doc/README.udp
@@ -0,0 +1,35 @@
+Udp framework
+
+The udp framework is build on top of network framework and is designed
+to define new protocol or new command based on udp without modifying
+the network framework.
+
+The udp framework define a function udp_loop that take as argument
+a structure udp_ops (defined in include/net/udp.h) :
+
+struct udp_ops {
+   int (*prereq)(void *data);
+   int (*start)(void *data);
+   void *data;
+};
+
+The callback prereq define if all the requirements are
+valid before running the network/udp loop.
+
+The callback start define the first step in the network/udp loop,
+and it may also be used to configure a timemout and udp handler.
+
+The pointer data is used to store private data that
+could be used by both callback.
+
+A simple example to use this framework:
+
+static struct udp_ops udp_ops = {
+   .prereq = wmp_prereq,
+   .start = wmp_start,
+   .data = NULL,
+};
+
+...
+
+err = udp_loop(&udp_ops);
diff --git a/include/net.h b/include/net.h
index 1bf9867..2191071 100644
--- a/include/net.h
+++ b/include/net.h
@@ -551,7 +551,7 @@ extern int  net_restart_wrap;   /* Tried all 
network devices */
 
 enum proto_t {
BOOTP, RARP, ARP, TFTPGET, DHCP, PING, DNS, NFS, CDP, NETCONS, SNTP,
-   TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT, WOL
+   TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT, WOL, UDP
 };
 
 extern charnet_boot_file_name[1024];/* Boot File name */
diff --git a/include/net/udp.h b/include/net/udp.h
new file mode 100644
index 000..2ae56e8
--- /dev/null
+++ b/include/net/udp.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2020 Philippe Reynes 
+ */
+
+#ifndef __UDP
+#define __UDP
+
+/**
+ * struct udp_ops - function to handle udp packet
+ *
+ * This structure provides the function to handle udp packet in
+ * the network loop.
+ *
+ * @prereq: callback called to check the requirement
+ * @start: callback called to start the protocol/feature
+ * @data: pointer to store private data (used by prereq and start)
+ */
+struct udp_ops {
+   int (*prereq)(void *data);
+   int (*start)(void *data);
+   void *data;
+};
+
+int udp_prereq(void);
+
+int udp_start(void);
+
+/**
+ * udp_loop() - network loop for udp protocol
+ *
+ * Launch a network loop for udp protocol and use callbacks
+ * provided in parameter @ops to initialize the loop, and then
+ * to handle udp packet.
+ *
+ * @ops: udp callback
+ * @return: 0 if success, otherwise < 0 on error
+ */
+int udp_loop(struct udp_ops *ops);
+
+#endif
diff --git a/net/Kconfig b/net/Kconfig
index 6874b55..1b3e420 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -8,6 +8,12 @@ menuconfig NET
 
 if NET
 
+config PROT_UDP
+   bool "Enable generic udp framework"
+   help
+ Enable a generic udp framework that allows defining a custom
+ handler for udp protocol.
+
 config BOOTP_SEND_HOSTNAME
bool "Send hostname to DNS server"
help
diff --git a/net/Makefile b/net/Makefile
index fef71b9..76527f7 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_CMD_SNTP) += sntp.o
 obj-$(CONFIG_CMD_TFTPBOOT) += tftp.o
 obj-$(CONFIG_UDP_FUNCTION_FASTBOOT)  += fastboot.o
 obj-$(CONFIG_CMD_WOL)  += wol.o
+obj-$(CONFIG_PROT_UDP) += udp.o
 
 # Disable this warning as it is triggered by:
 # sprintf(buf, index ? "foo%d" : "foo", index)
diff --git a/net/net.c b/net/net.c
index 28d9eeb..1ce0eb5 100644
--- a/net/net.c
+++ b/net/net.c
@@ -102,6 +102,7 @@
 #if defined(CONFIG_CMD_PCAP)
 #include 
 #endif
+#include 
 #if defined(CONFIG_LED_STATUS)
 #include 
 #include 
@@ -544,6 +545,9 @@ restart:
break;
}
 
+   if (IS_ENABLED(CONFIG_PROT_UDP) && protocol == UDP)
+   udp_start();
+
break;
}
 
@@ -1364,6 +1368,

[PATCH 2/2] fit: cipher: aes: allow to read the IV in the FIT image

2020-09-17 Thread Philippe Reynes
This commit add the support in u-boot to read the IV
in the FIT image instead of u-boot device tree.

Signed-off-by: Philippe Reynes 
---
 common/image-cipher.c | 22 +++---
 1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/common/image-cipher.c b/common/image-cipher.c
index 09869f7..4ca9eec 100644
--- a/common/image-cipher.c
+++ b/common/image-cipher.c
@@ -94,9 +94,11 @@ static int fit_image_setup_decrypt(struct image_cipher_info 
*info,
return -1;
}
 
+   info->iv = fdt_getprop(fit, cipher_noffset, "iv", NULL);
info->ivname = fdt_getprop(fit, cipher_noffset, "iv-name-hint", NULL);
-   if (!info->ivname) {
-   printf("Can't get IV name\n");
+
+   if (!info->iv && !info->ivname) {
+   printf("Can't get IV or IV name\n");
return -1;
}
 
@@ -120,8 +122,12 @@ static int fit_image_setup_decrypt(struct 
image_cipher_info *info,
 * Search the cipher node in the u-boot fdt
 * the path should be: /cipher/key---
 */
-   snprintf(node_path, sizeof(node_path), "/%s/key-%s-%s-%s",
-FIT_CIPHER_NODENAME, algo_name, info->keyname, info->ivname);
+   if (info->ivname)
+   snprintf(node_path, sizeof(node_path), "/%s/key-%s-%s-%s",
+FIT_CIPHER_NODENAME, algo_name, info->keyname, 
info->ivname);
+   else
+   snprintf(node_path, sizeof(node_path), "/%s/key-%s-%s",
+FIT_CIPHER_NODENAME, algo_name, info->keyname);
 
noffset = fdt_path_offset(fdt, node_path);
if (noffset < 0) {
@@ -137,10 +143,12 @@ static int fit_image_setup_decrypt(struct 
image_cipher_info *info,
}
 
/* read iv */
-   info->iv = fdt_getprop(fdt, noffset, "iv", NULL);
if (!info->iv) {
-   printf("Can't get IV in cipher node '%s'\n", node_path);
-   return -1;
+   info->iv = fdt_getprop(fdt, noffset, "iv", NULL);
+   if (!info->iv) {
+   printf("Can't get IV in cipher node '%s'\n", node_path);
+   return -1;
+   }
}
 
return 0;
-- 
2.7.4



[PATCH 1/2] fit: cipher: aes: allow to store the IV in the FIT image

2020-09-17 Thread Philippe Reynes
Binaries may be encrypted in a FIT image with AES. This
algo needs a key and an IV (Initialization Vector). The
IV is provided in a file (pointer by iv-name-hint in the
ITS file) when building the ITB file.

This commits adds provide an alternative way to manage
the IV. If the property iv-name-hint is not provided in
the ITS file, the tool mkimage will generate an random
IV and store it in the FIT image.

Signed-off-by: Philippe Reynes 
---
 include/image.h   |  2 +-
 include/u-boot/aes.h  |  6 +++--
 lib/aes/aes-encrypt.c | 22 +++
 tools/image-host.c| 61 +--
 4 files changed, 72 insertions(+), 19 deletions(-)

diff --git a/include/image.h b/include/image.h
index 9a5a87d..10995b8 100644
--- a/include/image.h
+++ b/include/image.h
@@ -1463,7 +1463,7 @@ struct cipher_algo {
   unsigned char **cipher, int *cipher_len);
 
int (*add_cipher_data)(struct image_cipher_info *info,
-  void *keydest);
+  void *keydest, void *fit, int node_noffset);
 
int (*decrypt)(struct image_cipher_info *info,
   const void *cipher, size_t cipher_len,
diff --git a/include/u-boot/aes.h b/include/u-boot/aes.h
index 3228104..acbc50b 100644
--- a/include/u-boot/aes.h
+++ b/include/u-boot/aes.h
@@ -13,7 +13,8 @@
 int image_aes_encrypt(struct image_cipher_info *info,
  const unsigned char *data, int size,
  unsigned char **cipher, int *cipher_len);
-int image_aes_add_cipher_data(struct image_cipher_info *info, void *keydest);
+int image_aes_add_cipher_data(struct image_cipher_info *info, void *keydest,
+ void *fit, int node_noffset);
 #else
 int image_aes_encrypt(struct image_cipher_info *info,
  const unsigned char *data, int size,
@@ -22,7 +23,8 @@ int image_aes_encrypt(struct image_cipher_info *info,
return -ENXIO;
 }
 
-int image_aes_add_cipher_data(struct image_cipher_info *info, void *keydest)
+int image_aes_add_cipher_data(struct image_cipher_info *info, void *keydest,
+ void *fit, int node_noffset)
 {
return -ENXIO;
 }
diff --git a/lib/aes/aes-encrypt.c b/lib/aes/aes-encrypt.c
index de00a83..a6d1720 100644
--- a/lib/aes/aes-encrypt.c
+++ b/lib/aes/aes-encrypt.c
@@ -74,7 +74,8 @@ int image_aes_encrypt(struct image_cipher_info *info,
return ret;
 }
 
-int image_aes_add_cipher_data(struct image_cipher_info *info, void *keydest)
+int image_aes_add_cipher_data(struct image_cipher_info *info, void *keydest,
+ void *fit, int node_noffset)
 {
int parent, node;
char name[128];
@@ -97,8 +98,13 @@ int image_aes_add_cipher_data(struct image_cipher_info 
*info, void *keydest)
goto done;
 
/* Either create or overwrite the named key node */
-   snprintf(name, sizeof(name), "key-%s-%s-%s",
-info->name, info->keyname, info->ivname);
+   if (info->ivname)
+   snprintf(name, sizeof(name), "key-%s-%s-%s",
+info->name, info->keyname, info->ivname);
+   else
+   snprintf(name, sizeof(name), "key-%s-%s",
+info->name, info->keyname);
+
node = fdt_subnode_offset(keydest, parent, name);
if (node == -FDT_ERR_NOTFOUND) {
node = fdt_add_subnode(keydest, parent, name);
@@ -116,9 +122,17 @@ int image_aes_add_cipher_data(struct image_cipher_info 
*info, void *keydest)
ret = node;
}
 
-   if (!ret)
+   if (ret)
+   goto done;
+
+   if (info->ivname)
+   /* Store the IV in the u-boot device tree */
ret = fdt_setprop(keydest, node, "iv",
  info->iv, info->cipher->iv_len);
+   else
+   /* Store the IV in the FIT image */
+   ret = fdt_setprop(fit, node_noffset, "iv",
+ info->iv, info->cipher->iv_len);
 
if (!ret)
ret = fdt_setprop(keydest, node, "key",
diff --git a/tools/image-host.c b/tools/image-host.c
index 3d52593..8886bef 100644
--- a/tools/image-host.c
+++ b/tools/image-host.c
@@ -320,6 +320,36 @@ err:
return ret;
 }
 
+static int get_random_data(void *data, int size)
+{
+   unsigned char *tmp = data;
+   struct timespec date;
+   int i, ret = 0;
+
+   if (!tmp) {
+   printf("%s: pointer data is NULL\n", __func__);
+   ret = -1;
+   goto out;
+   }
+
+   ret = clock_gettime(CLOCK_MONOTONIC, &date);
+   if (ret < 0) {
+   printf("%s: clock_gettime has failed (err=%d, str=%s)\n",
+  __func__, ret, strerror(ret));
+  

Re: U-Boot FIT Signature Verification

2020-09-16 Thread Philippe REYNES
Hi Heinrich,

> On 9/11/20 7:26 PM, Andrii Voloshyn wrote:
>> Hi there,
>> 
>> Does U-boot take into account certificate expiration date when verifying 
>> signed
>> images in FIT? In other words, is date stored along with the public key in 
>> DTB
>> file?
>> 
>> Cheers,
>> Andy
>> 
> 
> Hello Philippe,
> 
> looking at padding_pkcs_15_verify() in lib/rsa/rsa-verify.c I cannot
> find a comparison of the date on which an image was signed with the
> expiry date of the certificate. Shouldn't there be a check? Or did I
> simply look into the wrong function?

This function only check the padding using the algorithm pkcs-1.5 as
defined here : https://tools.ietf.org/html/rfc3447#section-9.2
It doesn't check the certificate validity.

I don't remember to have see a date checked in the signature process.
If all informations are (or may be) available at runtime, we may
add it.

> Best regards
> 
> Heinrich

Best regards,
Philippe


Re: [PATCH v2 3/3] cmd/button: return button status

2020-09-14 Thread Philippe REYNES


> To make the button command useful in a shell script it should return the
> status of the button:
> 
> * 0 (true) - pressed, on
> * 1 (false) - not pressed, off
> 
> The button command takes only one argument. Correct maxargs.
> 
> Adjust the Python unit test.
> 
> Signed-off-by: Heinrich Schuchardt 

Reviewed-by: Philippe Reynes 

> ---
> v2:
> adjust Python unit test
> ---
> cmd/button.c | 4 ++--
> test/py/tests/test_button.py | 34 ++
> 2 files changed, 28 insertions(+), 10 deletions(-)
> 
> diff --git a/cmd/button.c b/cmd/button.c
> index 84ad1653c7..64c5a8fa04 100644
> --- a/cmd/button.c
> +++ b/cmd/button.c
> @@ -75,11 +75,11 @@ int do_button(struct cmd_tbl *cmdtp, int flag, int argc,
> char *const argv[])
> 
> ret = show_button_state(dev);
> 
> - return 0;
> + return !ret;
> }
> 
> U_BOOT_CMD(
> - button, 4, 1, do_button,
> + button, 2, 1, do_button,
> "manage buttons",
> " \tGet button state\n"
> "button list\t\tShow a list of buttons"
> diff --git a/test/py/tests/test_button.py b/test/py/tests/test_button.py
> index eadd9dd613..3b7f148c8f 100644
> --- a/test/py/tests/test_button.py
> +++ b/test/py/tests/test_button.py
> @@ -4,16 +4,34 @@ import pytest
> 
> @pytest.mark.boardspec('sandbox')
> @pytest.mark.buildconfigspec('cmd_button')
> -def test_button_exit_statuses(u_boot_console):
> - """Test that non-input button commands correctly return the command
> - success/failure status."""
> +def test_button_list(u_boot_console):
> + """Test listing buttons"""
> 
> - expected_response = 'rc:0'
> response = u_boot_console.run_command('button list; echo rc:$?')
> - assert(expected_response in response)
> + assert('button1' in response)
> + assert('button2' in response)
> + assert('rc:0' in response)
> +
> +@pytest.mark.boardspec('sandbox')
> +@pytest.mark.buildconfigspec('cmd_button')
> +@pytest.mark.buildconfigspec('cmd_gpio')
> +def test_button_return_code(u_boot_console):
> + """Test correct reporting of the button status
> +
> + The sandbox gpio driver reports the last output value as input value.
> + We can use this in our test to emulate different input statuses.
> + """
> +
> + u_boot_console.run_command('gpio set a3; gpio input a3');
> + response = u_boot_console.run_command('button button1; echo rc:$?')
> + assert('on' in response)
> + assert('rc:0' in response)
> +
> + u_boot_console.run_command('gpio clear a3; gpio input a3');
> response = u_boot_console.run_command('button button1; echo rc:$?')
> - assert(expected_response in response)
> + assert('off' in response)
> + assert('rc:1' in response)
> 
> - expected_response = 'rc:1'
> response = u_boot_console.run_command('button nonexistent-button; echo rc:$?')
> - assert(expected_response in response)
> + assert('not found' in response)
> + assert('rc:1' in response)
> --
> 2.28.0


Re: [PATCH v2 1/3] test: sharpen button label unit test

2020-09-14 Thread Philippe REYNES


> Using different strings for the device tree node labels and the label
> property of buttons sharpens the button label unit test.
> 
> Signed-off-by: Heinrich Schuchardt 

Reviewed-by: Philippe Reynes 

> ---
> v2:
> new patch
> ---
> arch/sandbox/dts/sandbox.dtsi | 8 
> arch/sandbox/dts/test.dts | 8 
> test/dm/button.c | 6 +++---
> test/py/tests/test_button.py | 2 +-
> 4 files changed, 12 insertions(+), 12 deletions(-)
> 
> diff --git a/arch/sandbox/dts/sandbox.dtsi b/arch/sandbox/dts/sandbox.dtsi
> index c76ecc013c..0faad3f319 100644
> --- a/arch/sandbox/dts/sandbox.dtsi
> +++ b/arch/sandbox/dts/sandbox.dtsi
> @@ -18,14 +18,14 @@
> buttons {
> compatible = "gpio-keys";
> 
> - summer {
> + btn1 {
> gpios = <&gpio_a 3 0>;
> - label = "summer";
> + label = "button1";
> };
> 
> - christmas {
> + btn2 {
> gpios = <&gpio_a 4 0>;
> - label = "christmas";
> + label = "button2";
> };
> };
> 
> diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
> index 9f45c48e4e..395d5f5e56 100644
> --- a/arch/sandbox/dts/test.dts
> +++ b/arch/sandbox/dts/test.dts
> @@ -54,14 +54,14 @@
> buttons {
> compatible = "gpio-keys";
> 
> - summer {
> + btn1 {
> gpios = <&gpio_a 3 0>;
> - label = "summer";
> + label = "button1";
> };
> 
> - christmas {
> + btn2 {
> gpios = <&gpio_a 4 0>;
> - label = "christmas";
> + label = "button2";
> };
> };
> 
> diff --git a/test/dm/button.c b/test/dm/button.c
> index 9117801736..ecaa47cf5f 100644
> --- a/test/dm/button.c
> +++ b/test/dm/button.c
> @@ -57,17 +57,17 @@ static int dm_test_button_label(struct unit_test_state 
> *uts)
> {
> struct udevice *dev, *cmp;
> 
> - ut_assertok(button_get_by_label("summer", &dev));
> + ut_assertok(button_get_by_label("button1", &dev));
> ut_asserteq(1, device_active(dev));
> ut_assertok(uclass_get_device(UCLASS_BUTTON, 1, &cmp));
> ut_asserteq_ptr(dev, cmp);
> 
> - ut_assertok(button_get_by_label("christmas", &dev));
> + ut_assertok(button_get_by_label("button2", &dev));
> ut_asserteq(1, device_active(dev));
> ut_assertok(uclass_get_device(UCLASS_BUTTON, 2, &cmp));
> ut_asserteq_ptr(dev, cmp);
> 
> - ut_asserteq(-ENODEV, button_get_by_label("spring", &dev));
> + ut_asserteq(-ENODEV, button_get_by_label("nobutton", &dev));
> 
> return 0;
> }
> diff --git a/test/py/tests/test_button.py b/test/py/tests/test_button.py
> index 98067a98f2..eadd9dd613 100644
> --- a/test/py/tests/test_button.py
> +++ b/test/py/tests/test_button.py
> @@ -11,7 +11,7 @@ def test_button_exit_statuses(u_boot_console):
> expected_response = 'rc:0'
> response = u_boot_console.run_command('button list; echo rc:$?')
> assert(expected_response in response)
> - response = u_boot_console.run_command('button summer; echo rc:$?')
> + response = u_boot_console.run_command('button button1; echo rc:$?')
> assert(expected_response in response)
> 
> expected_response = 'rc:1'
> --
> 2.28.0


Re: [PATCH v2 2/3] drivers: gpio: keep output value for input on sandbox

2020-09-14 Thread Philippe REYNES


> For testing purposes keep the output value when switching to input.
> This allows us to manipulate the input value via the gpio command.
> 
> Signed-off-by: Heinrich Schuchardt 

Reviewed-by: Philippe Reynes 

> ---
> v2:
> new patch
> ---
> drivers/gpio/sandbox.c | 10 +-
> 1 file changed, 9 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpio/sandbox.c b/drivers/gpio/sandbox.c
> index c2f80472b8..eb2600de31 100644
> --- a/drivers/gpio/sandbox.c
> +++ b/drivers/gpio/sandbox.c
> @@ -185,7 +185,15 @@ static int sb_gpio_set_dir_flags(struct udevice *dev,
> unsigned int offset,
> 
> dir_flags = get_gpio_dir_flags(dev, offset);
> 
> - *dir_flags = flags;
> + /*
> + * For testing purposes keep the output value when switching to input.
> + * This allows us to manipulate the input value via the gpio command.
> + */
> + if (flags & GPIOD_IS_IN)
> + *dir_flags = (flags & ~GPIOD_IS_OUT_ACTIVE) |
> + (*dir_flags & GPIOD_IS_OUT_ACTIVE);
> + else
> + *dir_flags = flags;
> 
> return 0;
> }
> --
> 2.28.0


[PATCH v3 2/2] sandbox: enable support of generic udp protocol

2020-09-11 Thread Philippe Reynes
This commit enable the support of the generic udp protocol.

Signed-off-by: Philippe Reynes 
Reviewed-by: Simon Glass 
---

Changelog:
v3:
- no change
v2:
- new patch in the serie

 configs/sandbox_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 6e9f029..5ceff7d 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -102,6 +102,7 @@ CONFIG_ENV_IS_NOWHERE=y
 CONFIG_ENV_IS_IN_EXT4=y
 CONFIG_ENV_EXT4_INTERFACE="host"
 CONFIG_ENV_EXT4_DEVICE_AND_PART="0:0"
+CONFIG_PROT_UDP=y
 CONFIG_BOOTP_SEND_HOSTNAME=y
 CONFIG_NETCONSOLE=y
 CONFIG_IP_DEFRAG=y
-- 
2.7.4



[PATCH v3 1/2] net: add a generic udp protocol

2020-09-11 Thread Philippe Reynes
This commit adds a generic udp protocol framework in the
network loop. So protocol based on udp may be implemented
without modifying the network loop (for example custom
wait magic packet).

Signed-off-by: Philippe Reynes 
Reviewed-by: Simon Glass 
---

Changelog:
v3:
- add file doc/README.udp
- add more comments on function udp_loop
- fix sentence in Kconfig
- use if (IS_ENABLE(...)) when it is possible
- avoid checking null pointer twice

v2:
- no change

 doc/README.udp| 35 +++
 include/net.h |  2 +-
 include/net/udp.h | 41 +
 net/Kconfig   |  6 ++
 net/Makefile  |  1 +
 net/net.c | 13 -
 net/udp.c | 46 ++
 7 files changed, 142 insertions(+), 2 deletions(-)
 create mode 100644 doc/README.udp
 create mode 100644 include/net/udp.h
 create mode 100644 net/udp.c

diff --git a/doc/README.udp b/doc/README.udp
new file mode 100644
index 000..da07257
--- /dev/null
+++ b/doc/README.udp
@@ -0,0 +1,35 @@
+Udp framework
+
+The udp framework is build on top of network framework and is designed
+to define new protocol or new command based on udp without modifying
+the network framework.
+
+The udp framework define a function udp_loop that take as argument
+a structure udp_ops (defined in include/net/udp.h) :
+
+struct udp_ops {
+   int (*prereq)(void *data);
+   int (*start)(void *data);
+   void *data;
+};
+
+The callback prereq define if all the requirements are
+valid before running the network/udp loop.
+
+The callback start define the first step in the network/udp loop,
+and it may also be used to configure a timemout and udp handler.
+
+The pointer data is used to store private data that
+could be used by both callback.
+
+A simple example to use this framework:
+
+static struct udp_ops udp_ops = {
+   .prereq = wmp_prereq,
+   .start = wmp_start,
+   .data = NULL,
+};
+
+...
+
+err = udp_loop(&udp_ops);
diff --git a/include/net.h b/include/net.h
index 1bf9867..2191071 100644
--- a/include/net.h
+++ b/include/net.h
@@ -551,7 +551,7 @@ extern int  net_restart_wrap;   /* Tried all 
network devices */
 
 enum proto_t {
BOOTP, RARP, ARP, TFTPGET, DHCP, PING, DNS, NFS, CDP, NETCONS, SNTP,
-   TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT, WOL
+   TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT, WOL, UDP
 };
 
 extern charnet_boot_file_name[1024];/* Boot File name */
diff --git a/include/net/udp.h b/include/net/udp.h
new file mode 100644
index 000..2ae56e8
--- /dev/null
+++ b/include/net/udp.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2020 Philippe Reynes 
+ */
+
+#ifndef __UDP
+#define __UDP
+
+/**
+ * struct udp_ops - function to handle udp packet
+ *
+ * This structure provides the function to handle udp packet in
+ * the network loop.
+ *
+ * @prereq: callback called to check the requirement
+ * @start: callback called to start the protocol/feature
+ * @data: pointer to store private data (used by prereq and start)
+ */
+struct udp_ops {
+   int (*prereq)(void *data);
+   int (*start)(void *data);
+   void *data;
+};
+
+int udp_prereq(void);
+
+int udp_start(void);
+
+/**
+ * udp_loop() - network loop for udp protocol
+ *
+ * Launch a network loop for udp protocol and use callbacks
+ * provided in parameter @ops to initialize the loop, and then
+ * to handle udp packet.
+ *
+ * @ops: udp callback
+ * @return: 0 if success, otherwise < 0 on error
+ */
+int udp_loop(struct udp_ops *ops);
+
+#endif
diff --git a/net/Kconfig b/net/Kconfig
index 6874b55..1b3e420 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -8,6 +8,12 @@ menuconfig NET
 
 if NET
 
+config PROT_UDP
+   bool "Enable generic udp framework"
+   help
+ Enable a generic udp framework that allows defining a custom
+ handler for udp protocol.
+
 config BOOTP_SEND_HOSTNAME
bool "Send hostname to DNS server"
help
diff --git a/net/Makefile b/net/Makefile
index fef71b9..76527f7 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_CMD_SNTP) += sntp.o
 obj-$(CONFIG_CMD_TFTPBOOT) += tftp.o
 obj-$(CONFIG_UDP_FUNCTION_FASTBOOT)  += fastboot.o
 obj-$(CONFIG_CMD_WOL)  += wol.o
+obj-$(CONFIG_PROT_UDP) += udp.o
 
 # Disable this warning as it is triggered by:
 # sprintf(buf, index ? "foo%d" : "foo", index)
diff --git a/net/net.c b/net/net.c
index 28d9eeb..1ce0eb5 100644
--- a/net/net.c
+++ b/net/net.c
@@ -102,6 +102,7 @@
 #if defined(CONFIG_CMD_PCAP)
 #include 
 #endif
+#include 
 #if defined(CONFIG_LED_STATUS)
 #include 
 #include 
@@ -544,6 +545,9 @@ restart:
break;
}
 
+   if (IS_ENABLED(CONFIG_PROT_UDP) && protocol == UDP)
+   udp_start();
+
break;
}
 
@@ -1364,6 +1368,

Re: Improvements to FIT ciphering

2020-09-10 Thread Philippe REYNES
Hi Patrick,

Sorry for the late answer, I was very busy in the beginning of september

>> 
>> I agree that IV should be set in the FIT.
>> 
>> So in the dts, we may have:
>> cipher {
>> algo = "aes256";
>> key-name-hint = "aeskey";
>> iv = "aesiv";
>> };
>> or (I propose) :
>> cipher {
>> algo = "aes256";
>> key-name-hint = "aeskey";
>> iv-name-hint = "aesiv";
>> iv-in-fit;
>> };
>> 
>> I think that both solution should work ...
>> 
>> Have you planned to implement this change/feature ?
>> (otherwise I will try to found some time for it,
>> it is a really nice improvement).
> 
> Hi Philippe,
> 
> here is what I had in mind, in the .its we would put:
> 
> cipher {
> algo = "aes256";
> key-name-hint = "aeskey";
> };
> 
> when mkimage processes this it opens /dev/urandom to generate a unique
> IV. It then uses this IV to perform the encryption and writes it IV to
> the .fit image like so:
> 
> cipher {
> algo = "aes256";
> key-name-hint = "aeskey";
> iv = <0xa16e090c 0x7e116bf8 0x75c44329 0x3278c74d>;
> }
> 
> I don't think there is a need for a "iv-in-fit" property and
> "iv-name-hint" can be deprecated.

I think that we should keep the compatibility with previous code.
If a company/project has started to used iv in the u-boot device tree,
may be they want to continue without changing the format.

Idea 1:
if there is a property "iv-name-hint" in the FIT image, mkimage uses
the old format, and put the iv in the u-boot device tree. Otherwise,
mkimage generate a random iv an put it in the FIT image (recommanded solution).

Idea 2:
We manage four cases according to the properties in the its file:
- property "iv-name-hint" and no flag "iv-in-fit" :
  => the iv is static and added in the u-boot device tree (actual scheme)
- property "iv-name-hint" and flag "iv-in-fit" : 
  => the iv is static and added in the FIT image
- no property "iv-name-hint" and no flag "iv-in-fit" :
  => the iv is generated and added to the u-boot device tree
- no property "iv-name-hint" and flag "iv-in-fit" :
  => the iv is generated and added in the FIT image (recomanded scheme)


>> > However, if adding "hashed-nodes" and "hashed-strings" properties to
>> > the image signature is acceptable we can still support signing
>> > ciphered images with no problems.
>> 
>> I think that everything should be added to the signature. I think it's
>> simpler and more safe.
>> 
>> Have you planned to implement this/propose a patch please ?
>> (of course, if not, I will try to found some time)
> 
> Unfortunately right now it is crunch time at $DAYJOB to meet a
> deadline by the end of September, so I don't have much (if any) time
> to dedicate to working on U-Boot right now.
> 
> There are actually five issues on my list to address in U-Boot/mkimage:
> 
> * mkimage needs to generate encryption IV using /dev/urandom
> * FIT image signatures need to include cipher node
> * AES-GCM cipher support
> * mkimage -B option doesn't zero padding bytes
> * mkimage -B option unnecessarily pads the end of the image

I've got a lot of work too,  so I can't do all those features.
But I'll try to work on the (random) IV generation and set it in
the FIT image.


> I was planning on working through these when I get time, but I have
> not started on any of them yet. So, if you have time (and energy),
> please, go ahead :)

I'll do my best to start this work.

 
> Best regards,
> 
> Patrick

Best regards,
Philippe


Re: [PATCH 1/1] cmd/button: return button status

2020-09-04 Thread Philippe REYNES



> To make the button command useful in a shell script it should return the
> status of the button:
> 
> * 0 (true) - pressed, on
> * 1 (false) - not pressed, off
> 
> The button command takes only one argument. Correct maxargs.
> 
> Signed-off-by: Heinrich Schuchardt 

Reviewed-by: Philippe Reynes 

> ---
> cmd/button.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/cmd/button.c b/cmd/button.c
> index 84ad1653c7..64c5a8fa04 100644
> --- a/cmd/button.c
> +++ b/cmd/button.c
> @@ -75,11 +75,11 @@ int do_button(struct cmd_tbl *cmdtp, int flag, int argc,
> char *const argv[])
> 
> ret = show_button_state(dev);
> 
> - return 0;
> + return !ret;
> }
> 
> U_BOOT_CMD(
> - button, 4, 1, do_button,
> + button, 2, 1, do_button,
> "manage buttons",
> " \tGet button state\n"
> "button list\t\tShow a list of buttons"
> --
> 2.28.0


Re: [PATCH] net: add a generic udp protocol

2020-08-31 Thread Philippe REYNES
Hi Tom

> On Fri, Aug 21, 2020 at 07:55:05PM +0200, Philippe Reynes wrote:
> 
>> This commit adds a generic udp protocol framework in the
>> network loop. So protocol based on udp may be implemented
>> without modifying the network loop (for example custom
>> wait magic packet).
>> 
>> Signed-off-by: Philippe Reynes 
>> ---
>> include/net.h | 2 +-
>> include/net/udp.h | 31 +++
>> net/Kconfig | 6 ++
>> net/Makefile | 1 +
>> net/net.c | 15 ++-
>> net/udp.c | 48 
>> 6 files changed, 101 insertions(+), 2 deletions(-)
>> create mode 100644 include/net/udp.h
>> create mode 100644 net/udp.c
> 
> At minimum we need to enable this on sandbox. Would it be possible to
> test this somehow on sandbox (where we have networking) with netcat or
> something from the host?

I've sent a v2 with this feature enable on sandbox.

I have tested it on sandbox by adding a simple/silly command "wait for magic 
packet"
(using debug code). I'm looking for a way to add a test in test/dm/eth.c or
test/py/tests/test_net.py.

> --
> Tom

Philippe


[PATCH v2 2/2] sandbox: enable support of generic udp protocol

2020-08-31 Thread Philippe Reynes
This commit enable the support of the generic udp protocol.

Signed-off-by: Philippe Reynes 
---

Changelog:
v2:
- new patch in the serie

 configs/sandbox_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 6e9f029..5ceff7d 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -102,6 +102,7 @@ CONFIG_ENV_IS_NOWHERE=y
 CONFIG_ENV_IS_IN_EXT4=y
 CONFIG_ENV_EXT4_INTERFACE="host"
 CONFIG_ENV_EXT4_DEVICE_AND_PART="0:0"
+CONFIG_PROT_UDP=y
 CONFIG_BOOTP_SEND_HOSTNAME=y
 CONFIG_NETCONSOLE=y
 CONFIG_IP_DEFRAG=y
-- 
2.7.4



[PATCH v2 1/2] net: add a generic udp protocol

2020-08-31 Thread Philippe Reynes
This commit adds a generic udp protocol framework in the
network loop. So protocol based on udp may be implemented
without modifying the network loop (for example custom
wait magic packet).

Signed-off-by: Philippe Reynes 
---

Changelog:
v2:
- no change

 include/net.h |  2 +-
 include/net/udp.h | 31 +++
 net/Kconfig   |  6 ++
 net/Makefile  |  1 +
 net/net.c | 15 ++-
 net/udp.c | 48 
 6 files changed, 101 insertions(+), 2 deletions(-)
 create mode 100644 include/net/udp.h
 create mode 100644 net/udp.c

diff --git a/include/net.h b/include/net.h
index 1bf9867..2191071 100644
--- a/include/net.h
+++ b/include/net.h
@@ -551,7 +551,7 @@ extern int  net_restart_wrap;   /* Tried all 
network devices */
 
 enum proto_t {
BOOTP, RARP, ARP, TFTPGET, DHCP, PING, DNS, NFS, CDP, NETCONS, SNTP,
-   TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT, WOL
+   TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT, WOL, UDP
 };
 
 extern charnet_boot_file_name[1024];/* Boot File name */
diff --git a/include/net/udp.h b/include/net/udp.h
new file mode 100644
index 000..f97df8d
--- /dev/null
+++ b/include/net/udp.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2020 Philippe Reynes 
+ */
+
+#ifndef __UDP
+#define __UDP
+
+/**
+ * struct udp_ops - function to handle udp packet
+ *
+ * This structure provides the function to handle udp packet in
+ * the network loop.
+ *
+ * @prereq: callback called to check the requirement
+ * @start: callback called to start the protocol/feature
+ * @data: pointer to store private data (used by prereq and start)
+ */
+struct udp_ops {
+   int (*prereq)(void *data);
+   int (*start)(void *data);
+   void *data;
+};
+
+int udp_prereq(void);
+
+int udp_start(void);
+
+int udp_loop(struct udp_ops *h);
+
+#endif
diff --git a/net/Kconfig b/net/Kconfig
index 6874b55..db8d796 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -8,6 +8,12 @@ menuconfig NET
 
 if NET
 
+config PROT_UDP
+   bool "Enable generic udp framework"
+   help
+ Enable a generic udp framework that allow to define custom
+ handler for udp protocol.
+
 config BOOTP_SEND_HOSTNAME
bool "Send hostname to DNS server"
help
diff --git a/net/Makefile b/net/Makefile
index fef71b9..76527f7 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_CMD_SNTP) += sntp.o
 obj-$(CONFIG_CMD_TFTPBOOT) += tftp.o
 obj-$(CONFIG_UDP_FUNCTION_FASTBOOT)  += fastboot.o
 obj-$(CONFIG_CMD_WOL)  += wol.o
+obj-$(CONFIG_PROT_UDP) += udp.o
 
 # Disable this warning as it is triggered by:
 # sprintf(buf, index ? "foo%d" : "foo", index)
diff --git a/net/net.c b/net/net.c
index 28d9eeb..f6ae814 100644
--- a/net/net.c
+++ b/net/net.c
@@ -102,6 +102,7 @@
 #if defined(CONFIG_CMD_PCAP)
 #include 
 #endif
+#include 
 #if defined(CONFIG_LED_STATUS)
 #include 
 #include 
@@ -540,6 +541,11 @@ restart:
wol_start();
break;
 #endif
+#if defined(CONFIG_PROT_UDP)
+   case UDP:
+   udp_start();
+   break;
+#endif
default:
break;
}
@@ -1364,6 +1370,13 @@ static int net_check_prereq(enum proto_t protocol)
}
goto common;
 #endif
+#if defined(CONFIG_PROT_UDP)
+   case UDP:
+   if (udp_prereq())
+   return 1;
+   goto common;
+#endif
+
 #if defined(CONFIG_CMD_NFS)
case NFS:
 #endif
@@ -1375,7 +1388,7 @@ static int net_check_prereq(enum proto_t protocol)
return 1;
}
 #ifdefined(CONFIG_CMD_PING) || defined(CONFIG_CMD_SNTP) || \
-   defined(CONFIG_CMD_DNS)
+   defined(CONFIG_CMD_DNS) || defined(CONFIG_PROT_UDP)
 common:
 #endif
/* Fall through */
diff --git a/net/udp.c b/net/udp.c
new file mode 100644
index 000..2409ce4
--- /dev/null
+++ b/net/udp.c
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 Philippe Reynes 
+ */
+
+#include 
+#include 
+#include 
+
+static struct udp_ops *udp_ops;
+
+int udp_prereq(void)
+{
+   int ret = 0;
+
+   if (udp_ops && udp_ops->prereq)
+   ret = udp_ops->prereq(udp_ops->data);
+
+   return ret;
+}
+
+int udp_start(void)
+{
+   int ret = -1;
+
+   if (udp_ops && udp_ops->start)
+   ret = udp_ops->start(udp_ops->data);
+   else
+   printf("%s: no start function defined\n", __func__);
+
+   return ret;
+}
+
+int udp_loop(struct udp_ops *ops)
+{
+   int ret = -1;
+
+   if (!ops) {
+   printf("%s: ops should not be null\n", __func__);
+   goto out;
+   }
+
+   udp_ops = ops;
+   ret = net_loop(UDP);
+
+ out:
+   return ret;
+}
-- 
2.7.4



Re: Improvements to FIT ciphering

2020-08-24 Thread Philippe REYNES
Hi Patrick,

>> 
>> Hi Patrick,
>> 
>> Sorry for this late anwser, I was very busy this week.
> 
> No problem!

Again, sorry I was off and then busy.

> Before I address your comments below, is there anything else I need to
> do with the previous patches I posted? I haven't contributed to U-Boot
> before and I'm not entirely sure of the correct process. Do I need to
> resubmit the patches with your reviewed-by tags included?

You have followed the correct process.
Your patches (and proposal) are fine.

>> > Hi Simon & Philippe,
>> > 
>> > I've been thinking about this some more and have added a few points
>> > below. I will need feedback before proposing any patches for the
>> > remaining issues.
>> > 
>> > On Fri, Jul 24, 2020 at 12:06 PM Patrick Oppenlander
>> >  wrote:
>> >> 
>> >> Issue #1
>> >> 
>> >> 
>> >> Currently, mkimage treats the IV in the same manner as the encryption
>> >> key. There is an iv-name-hint property which mkimage uses to read the
>> >> IV from a file in the keys directory. This can then be written to
>> >> u-boot.dtb along with the encryption key.
>> >> 
>> >> The problem with that is that u-boot.dtb is baked in at production
>> >> time and is generally not field upgradable. That means that the IV is
>> >> also baked in which is considered bad practice especially when using
>> >> CBC mode (see CBC IV attack). In general it is my understanding that
>> >> you should never use a key+IV twice regardless of cipher or mode.
>> >> 
>> >> In my opinion a better solution would have been to write the IV into
>> >> the FIT image instead of iv-name-hint (it's only 16 bytes!), and
>> >> regenerate it (/dev/random?) each and every time the data is ciphered.
>> >> 
>> > 
>> > If U-Boot needs to continue supporting AES-CBC I think the only option
>> > here is to deprecate the "iv-name-hint" property and replace it with
>> > an "iv" property. This should be possible in a backward-compatible
>> > manner.
>> 
>> I prefer to keep the support of aes-cbc, and I like the idea of storing
>> the IV in the FIT image.
>> 
>> But I don't really understand the issue with iv-name-hint. To stay
>> compatible, for example, we could simply add a propert "iv-store-in-fit"
>> in the device tree.
> 
> The IV must change each and every time the encryption is run. I am not
> sure how this can be achieved using "iv-name-hint" and storing the IV
> in the U-Boot FDT. Maybe I have missed something?
> 
> In the simplest case encrypting the same plaintext twice must not
> result in the same ciphertext as this leaks important information to
> an attacker (the plaintext payload is the same!). There are many
> examples of attacks against encryption where the IV is kept constant.
> 
> This is why I suggested replacing "iv-name-hint" with "iv". U-Boot can
> then search for "iv" first and (optionally?) fall back to
> "iv-name-hint" if "Iv" is not found. This should be a simple change.

I agree that IV should be set in the FIT.

So in the dts, we may have:
cipher {
algo = "aes256";
key-name-hint = "aeskey";
iv = "aesiv";
};
or (I propose) :
cipher {
algo = "aes256";
key-name-hint = "aeskey";
iv-name-hint = "aesiv";
iv-in-fit;
};

I think that both solution should work ...

Have you planned to implement this change/feature ?
(otherwise I will try to found some time for it,
it is a really nice improvement).

>> >> 
>> >> An even better solution is to use AES-GCM (or something similar) as
>> >> this includes the IV with the ciphertext, simplifying the above, and
>> >> also provides authentication addressing another issue (see below).
>> >> 
>> > 
>> > In my opinion it would be better to deprecate AES-CBC and replace it
>> > with AES-GCM. I can see no advantages to supporting both, and can see
>> > no reason to use AES-CBC over AES-GCM apart from a minor performance
>> > advantage.
>> 
>> I also think that AES-GCM is a really good idea.
>> 
>> But I prefer to keep aes-cbc support. And to go further, I think we may
>> support several algo (for example AES-CTR). The algo choice may change
>> depending on the project. The boot speed may be very important (or not).
> 
> That makes sense. There is also a code size advantage which may matter
> in some circumstances.
> 
> Perhaps we should add a "mode" property: "cbc", "ctr", "gcm", etc.
> 
>> >> Issue #2
>> >> ===
>> >> 
>> >> The current implementation uses encrypt-then-sign. I like this
>> >> approach as it means that the FIT image can be verified outside of
>> >> U-Boot without requiring encryption keys. It is also considered best
>> >> practise.
>> >> 
>> >> However, for this to be secure, the details of the cipher need to be
>> >> included in the signature, otherwise an attacker can change the cipher
>> >> or key/iv properties.
>> >> 
>> >> I do not believe that properties in the cipher node are currently
>> >> included when signin

[PATCH] net: add a generic udp protocol

2020-08-21 Thread Philippe Reynes
This commit adds a generic udp protocol framework in the
network loop. So protocol based on udp may be implemented
without modifying the network loop (for example custom
wait magic packet).

Signed-off-by: Philippe Reynes 
---
 include/net.h |  2 +-
 include/net/udp.h | 31 +++
 net/Kconfig   |  6 ++
 net/Makefile  |  1 +
 net/net.c | 15 ++-
 net/udp.c | 48 
 6 files changed, 101 insertions(+), 2 deletions(-)
 create mode 100644 include/net/udp.h
 create mode 100644 net/udp.c

diff --git a/include/net.h b/include/net.h
index 1bf9867..2191071 100644
--- a/include/net.h
+++ b/include/net.h
@@ -551,7 +551,7 @@ extern int  net_restart_wrap;   /* Tried all 
network devices */
 
 enum proto_t {
BOOTP, RARP, ARP, TFTPGET, DHCP, PING, DNS, NFS, CDP, NETCONS, SNTP,
-   TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT, WOL
+   TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT, WOL, UDP
 };
 
 extern charnet_boot_file_name[1024];/* Boot File name */
diff --git a/include/net/udp.h b/include/net/udp.h
new file mode 100644
index 000..f97df8d
--- /dev/null
+++ b/include/net/udp.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2020 Philippe Reynes 
+ */
+
+#ifndef __UDP
+#define __UDP
+
+/**
+ * struct udp_ops - function to handle udp packet
+ *
+ * This structure provides the function to handle udp packet in
+ * the network loop.
+ *
+ * @prereq: callback called to check the requirement
+ * @start: callback called to start the protocol/feature
+ * @data: pointer to store private data (used by prereq and start)
+ */
+struct udp_ops {
+   int (*prereq)(void *data);
+   int (*start)(void *data);
+   void *data;
+};
+
+int udp_prereq(void);
+
+int udp_start(void);
+
+int udp_loop(struct udp_ops *h);
+
+#endif
diff --git a/net/Kconfig b/net/Kconfig
index 6874b55..db8d796 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -8,6 +8,12 @@ menuconfig NET
 
 if NET
 
+config PROT_UDP
+   bool "Enable generic udp framework"
+   help
+ Enable a generic udp framework that allow to define custom
+ handler for udp protocol.
+
 config BOOTP_SEND_HOSTNAME
bool "Send hostname to DNS server"
help
diff --git a/net/Makefile b/net/Makefile
index fef71b9..76527f7 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_CMD_SNTP) += sntp.o
 obj-$(CONFIG_CMD_TFTPBOOT) += tftp.o
 obj-$(CONFIG_UDP_FUNCTION_FASTBOOT)  += fastboot.o
 obj-$(CONFIG_CMD_WOL)  += wol.o
+obj-$(CONFIG_PROT_UDP) += udp.o
 
 # Disable this warning as it is triggered by:
 # sprintf(buf, index ? "foo%d" : "foo", index)
diff --git a/net/net.c b/net/net.c
index 28d9eeb..f6ae814 100644
--- a/net/net.c
+++ b/net/net.c
@@ -102,6 +102,7 @@
 #if defined(CONFIG_CMD_PCAP)
 #include 
 #endif
+#include 
 #if defined(CONFIG_LED_STATUS)
 #include 
 #include 
@@ -540,6 +541,11 @@ restart:
wol_start();
break;
 #endif
+#if defined(CONFIG_PROT_UDP)
+   case UDP:
+   udp_start();
+   break;
+#endif
default:
break;
}
@@ -1364,6 +1370,13 @@ static int net_check_prereq(enum proto_t protocol)
}
goto common;
 #endif
+#if defined(CONFIG_PROT_UDP)
+   case UDP:
+   if (udp_prereq())
+   return 1;
+   goto common;
+#endif
+
 #if defined(CONFIG_CMD_NFS)
case NFS:
 #endif
@@ -1375,7 +1388,7 @@ static int net_check_prereq(enum proto_t protocol)
return 1;
}
 #ifdefined(CONFIG_CMD_PING) || defined(CONFIG_CMD_SNTP) || \
-   defined(CONFIG_CMD_DNS)
+   defined(CONFIG_CMD_DNS) || defined(CONFIG_PROT_UDP)
 common:
 #endif
/* Fall through */
diff --git a/net/udp.c b/net/udp.c
new file mode 100644
index 000..2409ce4
--- /dev/null
+++ b/net/udp.c
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 Philippe Reynes 
+ */
+
+#include 
+#include 
+#include 
+
+static struct udp_ops *udp_ops;
+
+int udp_prereq(void)
+{
+   int ret = 0;
+
+   if (udp_ops && udp_ops->prereq)
+   ret = udp_ops->prereq(udp_ops->data);
+
+   return ret;
+}
+
+int udp_start(void)
+{
+   int ret = -1;
+
+   if (udp_ops && udp_ops->start)
+   ret = udp_ops->start(udp_ops->data);
+   else
+   printf("%s: no start function defined\n", __func__);
+
+   return ret;
+}
+
+int udp_loop(struct udp_ops *ops)
+{
+   int ret = -1;
+
+   if (!ops) {
+   printf("%s: ops should not be null\n", __func__);
+   goto out;
+   }
+
+   udp_ops = ops;
+   ret = net_loop(UDP);
+
+ out:
+   return ret;
+}
-- 
2.7.4



Re: Improvements to FIT ciphering

2020-08-07 Thread Philippe REYNES
Hi Patrick,

Sorry for this late anwser, I was very busy this week.

> Hi Simon & Philippe,
> 
> I've been thinking about this some more and have added a few points
> below. I will need feedback before proposing any patches for the
> remaining issues.
> 
> On Fri, Jul 24, 2020 at 12:06 PM Patrick Oppenlander
>  wrote:
>> 
>> Issue #1
>> 
>> 
>> Currently, mkimage treats the IV in the same manner as the encryption
>> key. There is an iv-name-hint property which mkimage uses to read the
>> IV from a file in the keys directory. This can then be written to
>> u-boot.dtb along with the encryption key.
>> 
>> The problem with that is that u-boot.dtb is baked in at production
>> time and is generally not field upgradable. That means that the IV is
>> also baked in which is considered bad practice especially when using
>> CBC mode (see CBC IV attack). In general it is my understanding that
>> you should never use a key+IV twice regardless of cipher or mode.
>> 
>> In my opinion a better solution would have been to write the IV into
>> the FIT image instead of iv-name-hint (it's only 16 bytes!), and
>> regenerate it (/dev/random?) each and every time the data is ciphered.
>> 
> 
> If U-Boot needs to continue supporting AES-CBC I think the only option
> here is to deprecate the "iv-name-hint" property and replace it with
> an "iv" property. This should be possible in a backward-compatible
> manner.

I prefer to keep the support of aes-cbc, and I like the idea of storing
the IV in the FIT image.

But I don't really understand the issue with iv-name-hint. To stay
compatible, for example, we could simply add a propert "iv-store-in-fit"
in the device tree.


>> 
>> An even better solution is to use AES-GCM (or something similar) as
>> this includes the IV with the ciphertext, simplifying the above, and
>> also provides authentication addressing another issue (see below).
>> 
> 
> In my opinion it would be better to deprecate AES-CBC and replace it
> with AES-GCM. I can see no advantages to supporting both, and can see
> no reason to use AES-CBC over AES-GCM apart from a minor performance
> advantage.

I also think that AES-GCM is a really good idea.

But I prefer to keep aes-cbc support. And to go further, I think we may
support several  algo (for example AES-CTR). The algo choice may change
depending on the project. The boot speed may be very important (or not).

 
>> Issue #2
>> ===
>> 
>> The current implementation uses encrypt-then-sign. I like this
>> approach as it means that the FIT image can be verified outside of
>> U-Boot without requiring encryption keys. It is also considered best
>> practise.
>> 
>> However, for this to be secure, the details of the cipher need to be
>> included in the signature, otherwise an attacker can change the cipher
>> or key/iv properties.
>> 
>> I do not believe that properties in the cipher node are currently
>> included when signing a FIT configuration including an encrypted
>> image. That should be a simple fix. Fixing it for image signatures
>> might be a bit more tricky.
> 
> I have posted a patch [1] which Philippe has reviewed which includes
> the cipher node when signing a configuration.
> 
> It looks to be a much more intrusive (and incompatible) change to
> include the cipher node in an image signature. Perhaps it would be
> better for mkimage to issue a warning or error in this case and
> document why it is not recommended?

I don't see the issue, but I haven't looked deeply 

> I don't personally have a use case for signing an image. All of my FIT
> images use configuration signatures instead. Is there a common use
> case for which this needs to be solved or could we say that signing an
> encrypted image is simply not supported?

We may provide a warning, but not allowing it seems a bit "hard".
Is it really problematic to not sign the cipher node ?

>> Issue #3
>> ===
>> 
>> Due to the nature of encrypt-then-sign U-Boot can verify that the
>> ciphertext is unmodified, but it has no way of making sure that the
>> key used to encrypt the image matches the key in u-boot.fit used for
>> decryption. This can result in an attempt to boot gibberish and I
>> think it can open up certain attack vectors.
>> 
>> The best way I know of to fix this is to use an authenticated
>> encryption mode such as AES-GCM or something similar.
> 
> I still think this is the best approach.

I agree that supporting AES-GCM would increase the security,
so it is a really good idea.
But, I think that we should not impose aes-gcm.
 
> Patrick
> 
> [1] https://lists.denx.de/pipermail/u-boot/2020-July/421989.html


In few words, I like the idea of supporting AES-GCM.


Best regards,
Philippe


Re: [PATCH] mkimage: fit: include image cipher in configuration signature

2020-07-30 Thread Philippe REYNES
Hi Patrick,


> From: Patrick Oppenlander 
> 
> This patch addresses issue #2 for signed configurations.
> 
> -8<-

This "line" will be included in the commit message ;)

> Including the image cipher properties in the configuration signature
> prevents an attacker from modifying cipher, key or iv properties.
> 
> Signed-off-by: Patrick Oppenlander 


Reviewed-by: Philippe Reynes 


Regards,
Philippe

> ---
> tools/image-host.c | 17 +
> 1 file changed, 17 insertions(+)
> 
> diff --git a/tools/image-host.c b/tools/image-host.c
> index e5417beee5..3d52593e36 100644
> --- a/tools/image-host.c
> +++ b/tools/image-host.c
> @@ -744,6 +744,23 @@ static int fit_config_get_hash_list(void *fit, int
> conf_noffset,
> return -ENOMSG;
> }
> 
> + /* Add this image's cipher node if present */
> + noffset = fdt_subnode_offset(fit, image_noffset,
> + FIT_CIPHER_NODENAME);
> + if (noffset != -FDT_ERR_NOTFOUND) {
> + if (noffset < 0) {
> + printf("Failed to get cipher node in configuration '%s/%s' image '%s': 
> %s\n",
> + conf_name, sig_name, iname,
> + fdt_strerror(noffset));
> + return -EIO;
> + }
> + ret = fdt_get_path(fit, noffset, path, sizeof(path));
> + if (ret < 0)
> + goto err_path;
> + if (strlist_add(node_inc, path))
> + goto err_mem;
> + }
> +
> image_count++;
> }
> 
> --
> 2.27.0


Re: [PATCH v2 3/3] mkimage: fit: don't cipher ciphered data

2020-07-30 Thread Philippe REYNES
Hi Patrick,


> From: Patrick Oppenlander 
> 
> Previously, mkimage -F could be run multiple times causing already
> ciphered image data to be ciphered again.

Reviewed-by: Philippe Reynes 
 
> Signed-off-by: Patrick Oppenlander 


Regards,
Philippe


> ---
> tools/image-host.c | 15 ++-
> 1 file changed, 14 insertions(+), 1 deletion(-)
> 
> diff --git a/tools/image-host.c b/tools/image-host.c
> index b4603c5f01..e5417beee5 100644
> --- a/tools/image-host.c
> +++ b/tools/image-host.c
> @@ -482,7 +482,7 @@ int fit_image_cipher_data(const char *keydir, void 
> *keydest,
> const char *image_name;
> const void *data;
> size_t size;
> - int cipher_node_offset;
> + int cipher_node_offset, len;
> 
> /* Get image name */
> image_name = fit_get_name(fit, image_noffset, NULL);
> @@ -497,6 +497,19 @@ int fit_image_cipher_data(const char *keydir, void
> *keydest,
> return -1;
> }
> 
> + /*
> + * Don't cipher ciphered data.
> + *
> + * If the data-size-unciphered property is present the data for this
> + * image is already encrypted. This is important as 'mkimage -F' can be
> + * run multiple times on a FIT image.
> + */
> + if (fdt_getprop(fit, image_noffset, "data-size-unciphered", &len))
> + return 0;
> + if (len != -FDT_ERR_NOTFOUND) {
> + printf("Failure testing for data-size-unciphered\n");
> + return -1;
> + }
> 
> /* Process cipher node if present */
> cipher_node_offset = fdt_subnode_offset(fit, image_noffset,
> --
> 2.27.0


Re: [PATCH v2 2/3] mkimage: fit: handle FDT_ERR_NOSPACE when ciphering

2020-07-30 Thread Philippe REYNES
Hi Patrick,

> From: Patrick Oppenlander 
> 
> Also replace fdt_delprop/fdt_setprop with fdt_setprop as fdt_setprop can
> replace an existing property value.

Reviewed-by: Philippe Reynes 
 
> Signed-off-by: Patrick Oppenlander 


Regards,
Philippe


> ---
> tools/image-host.c | 19 ++-
> 1 file changed, 10 insertions(+), 9 deletions(-)
> 
> diff --git a/tools/image-host.c b/tools/image-host.c
> index dd7ecc4b60..b4603c5f01 100644
> --- a/tools/image-host.c
> +++ b/tools/image-host.c
> @@ -399,23 +399,24 @@ int fit_image_write_cipher(void *fit, int image_noffset,
> int noffset,
> {
> int ret = -1;
> 
> - /* Remove unciphered data */
> - ret = fdt_delprop(fit, image_noffset, FIT_DATA_PROP);
> - if (ret) {
> - printf("Can't remove data (err = %d)\n", ret);
> - goto out;
> - }
> -
> - /* Add ciphered data */
> + /* Replace data with ciphered data */
> ret = fdt_setprop(fit, image_noffset, FIT_DATA_PROP,
> data_ciphered, data_ciphered_len);
> + if (ret == -FDT_ERR_NOSPACE) {
> + ret = -ENOSPC;
> + goto out;
> + }
> if (ret) {
> - printf("Can't add ciphered data (err = %d)\n", ret);
> + printf("Can't replace data with ciphered data (err = %d)\n", ret);
> goto out;
> }
> 
> /* add non ciphered data size */
> ret = fdt_setprop_u32(fit, image_noffset, "data-size-unciphered", size);
> + if (ret == -FDT_ERR_NOSPACE) {
> + ret = -ENOSPC;
> + goto out;
> + }
> if (ret) {
> printf("Can't add unciphered data size (err = %d)\n", ret);
> goto out;
> --
> 2.27.0


Re: [PATCH 3/3] mkimage: fit: don't cipher ciphered data

2020-07-29 Thread Philippe REYNES
Hi Patrick,


> From: Patrick Oppenlander 
> 
> Previously, mkimage -F could be run multiple times causing already
> ciphered image data to be ciphered again.


Good catch, mkimage -F cipher data that are already ciphered,
generating a broken FIT image.


> Signed-off-by: Patrick Oppenlander 
> ---
> tools/image-host.c | 47 +++---
> 1 file changed, 32 insertions(+), 15 deletions(-)
> 
> diff --git a/tools/image-host.c b/tools/image-host.c
> index 87ef79ef53..12de9b5ec0 100644
> --- a/tools/image-host.c
> +++ b/tools/image-host.c
> @@ -397,33 +397,43 @@ int fit_image_write_cipher(void *fit, int image_noffset,
> int noffset,
> const void *data, size_t size,
> unsigned char *data_ciphered, int data_ciphered_len)
> {
> - int ret = -1;
> + /*
> + * fit_image_cipher_data() uses the presence of the data-size-unciphered
> + * property as a sentinel to detect whether the data for this image is
> + * already encrypted. This is important as:
> + * - 'mkimage -F' can be run multiple times on a FIT image
> + * - This function is in a retry loop to handle ENOSPC
> + */
> 
> - /* add non ciphered data size */
> + int ret;
> +
> + /* Add unciphered data size */
> ret = fdt_setprop_u32(fit, image_noffset, "data-size-unciphered", size);
> - if (ret == -FDT_ERR_NOSPACE) {
> - ret = -ENOSPC;
> - goto out;
> - }
> + if (ret == -FDT_ERR_NOSPACE)
> + return -ENOSPC;
> if (ret) {
> printf("Can't add unciphered data size (err = %d)\n", ret);
> - goto out;
> + return -EIO;
> }
> 
> - /* Add ciphered data */
> + /* Replace contents of data property with data_ciphered */
> ret = fdt_setprop(fit, image_noffset, FIT_DATA_PROP,
> data_ciphered, data_ciphered_len);
> if (ret == -FDT_ERR_NOSPACE) {
> - ret = -ENOSPC;
> - goto out;
> + /* Remove data-size-unciphered; data is not ciphered */
> + ret = fdt_delprop(fit, image_noffset, "data-size-unciphered");
> + if (ret) {
> + printf("Can't remove unciphered data size (err = %d)\n", ret);
> + return -EIO;
> + }
> + return -ENOSPC;
> }
> if (ret) {
> - printf("Can't add ciphered data (err = %d)\n", ret);
> - goto out;
> + printf("Can't replace data with ciphered data (err = %d)\n", ret);
> + return -EIO;
> }
> 
> - out:
> - return ret;
> + return 0;
> }

As for the second patch, I think that the loop is not an issue because
it always start with "fresh/clean" value (using a backup file).

So I am not sure that changes in this function are needed.


> static int
> @@ -482,7 +492,7 @@ int fit_image_cipher_data(const char *keydir, void 
> *keydest,
> const char *image_name;
> const void *data;
> size_t size;
> - int cipher_node_offset;
> + int cipher_node_offset, len;
> 
> /* Get image name */
> image_name = fit_get_name(fit, image_noffset, NULL);
> @@ -497,6 +507,13 @@ int fit_image_cipher_data(const char *keydir, void
> *keydest,
> return -1;
> }
> 
> + /* Don't cipher ciphered data */
> + if (fdt_getprop(fit, image_noffset, "data-size-unciphered", &len))
> + return 0;
> + if (len != -FDT_ERR_NOTFOUND) {
> + printf("Failure testing for data-size-unciphered\n");
> + return -1;
> + }

>From my point of view, it fixes an issue. But I see this solution more
as "workaround" than a clean solution.

As it fixes a real issue, we may start with it and then try to found a
"clean" solution.


> /* Process cipher node if present */
> cipher_node_offset = fdt_subnode_offset(fit, image_noffset, "cipher");
> --
> 2.27.0


Regards,
Philippe


Re: [PATCH 2/3] mkimage: fit: handle FDT_ERR_NOSPACE when ciphering

2020-07-29 Thread Philippe REYNES
Hi Patrick

> From: Patrick Oppenlander 
> 
> This meant that the order of operations had to change. If we replace the
> data property first then fail to add the data-size-unciphered property
> the data will be ciphered again when retrying.


This patch is good, but I disagree with the comment. It is not mandatory
to change the order of operation because when signing/ciphering we always
start from "fresh" file.

This "trick" is done in the function fit_handle_file(...)

Just before the loop, the tmpfile is rename in bakfile

sprintf(bakfile, "%s%s", tmpfile, ".bak");
rename(tmpfile, bakfile);

And in the loop, the first operation is to copy bakfile to tmpfile:

for (size_inc = 0; size_inc < 64 * 1024; size_inc += 1024) {
if (copyfile(bakfile, tmpfile) < 0) {
printf("Can't copy %s to %s\n", bakfile, tmpfile);
ret = -EIO;
break;
}
ret = fit_add_file_data(params, size_inc, tmpfile);
if (!ret || ret != -ENOSPC)
break;
}

So I think that we always cipher with unciphered data.


> Signed-off-by: Patrick Oppenlander 
> ---
> tools/image-host.c | 19 ++-
> 1 file changed, 10 insertions(+), 9 deletions(-)
> 
> diff --git a/tools/image-host.c b/tools/image-host.c
> index 8fa1b9aba7..87ef79ef53 100644
> --- a/tools/image-host.c
> +++ b/tools/image-host.c
> @@ -399,25 +399,26 @@ int fit_image_write_cipher(void *fit, int image_noffset,
> int noffset,
> {
> int ret = -1;
> 
> - /* Remove unciphered data */
> - ret = fdt_delprop(fit, image_noffset, FIT_DATA_PROP);
> + /* add non ciphered data size */
> + ret = fdt_setprop_u32(fit, image_noffset, "data-size-unciphered", size);
> + if (ret == -FDT_ERR_NOSPACE) {
> + ret = -ENOSPC;
> + goto out;
> + }
> if (ret) {
> - printf("Can't remove data (err = %d)\n", ret);
> + printf("Can't add unciphered data size (err = %d)\n", ret);
> goto out;
> }
> 
> /* Add ciphered data */
> ret = fdt_setprop(fit, image_noffset, FIT_DATA_PROP,
> data_ciphered, data_ciphered_len);
> - if (ret) {
> - printf("Can't add ciphered data (err = %d)\n", ret);
> + if (ret == -FDT_ERR_NOSPACE) {
> + ret = -ENOSPC;
> goto out;
> }
> -
> - /* add non ciphered data size */
> - ret = fdt_setprop_u32(fit, image_noffset, "data-size-unciphered", size);
> if (ret) {
> - printf("Can't add unciphered data size (err = %d)\n", ret);
> + printf("Can't add ciphered data (err = %d)\n", ret);
> goto out;
> }
> 
> --
> 2.27.0


Regards,
Philippe


Re: [PATCH 1/3] mkimage: fit: only process one cipher node

2020-07-29 Thread Philippe REYNES
Hi Patrick,

> From: Patrick Oppenlander 
> 
> Previously mkimage would process any node matching the regex cipher.*
> and apply the ciphers to the image data in the order they appeared in
> the FDT. This meant that data could be inadvertently ciphered multiple
> times.
> 
> Switch to processing a single cipher node which exactly matches
> FIT_CIPHER_NODENAME.
> 
> Signed-off-by: Patrick Oppenlander 
> ---
> tools/image-host.c | 56 +-
> 1 file changed, 21 insertions(+), 35 deletions(-)
> 
> diff --git a/tools/image-host.c b/tools/image-host.c
> index 9a83b7f675..8fa1b9aba7 100644
> --- a/tools/image-host.c
> +++ b/tools/image-host.c
> @@ -323,15 +323,15 @@ err:
> static int fit_image_setup_cipher(struct image_cipher_info *info,
> const char *keydir, void *fit,
> const char *image_name, int image_noffset,
> - const char *node_name, int noffset)
> + int noffset)
> {
> char *algo_name;
> char filename[128];
> int ret = -1;
> 
> if (fit_image_cipher_get_algo(fit, noffset, &algo_name)) {
> - printf("Can't get algo name for cipher '%s' in image '%s'\n",
> - node_name, image_name);
> + printf("Can't get algo name for cipher in image '%s'\n",
> + image_name);
> goto out;
> }
> 
> @@ -340,16 +340,16 @@ static int fit_image_setup_cipher(struct 
> image_cipher_info
> *info,
> /* Read the key name */
> info->keyname = fdt_getprop(fit, noffset, FIT_KEY_HINT, NULL);
> if (!info->keyname) {
> - printf("Can't get key name for cipher '%s' in image '%s'\n",
> - node_name, image_name);
> + printf("Can't get key name for cipher in image '%s'\n",
> + image_name);
> goto out;
> }
> 
> /* Read the IV name */
> info->ivname = fdt_getprop(fit, noffset, "iv-name-hint", NULL);
> if (!info->ivname) {
> - printf("Can't get iv name for cipher '%s' in image '%s'\n",
> - node_name, image_name);
> + printf("Can't get iv name for cipher in image '%s'\n",
> + image_name);
> goto out;
> }
> 
> @@ -428,8 +428,7 @@ int fit_image_write_cipher(void *fit, int image_noffset, 
> int
> noffset,
> static int
> fit_image_process_cipher(const char *keydir, void *keydest, void *fit,
> const char *image_name, int image_noffset,
> - const char *node_name, int node_noffset,
> - const void *data, size_t size,
> + int node_noffset, const void *data, size_t size,
> const char *cmdname)
> {
> struct image_cipher_info info;
> @@ -440,7 +439,7 @@ fit_image_process_cipher(const char *keydir, void 
> *keydest,
> void *fit,
> memset(&info, 0, sizeof(info));
> 
> ret = fit_image_setup_cipher(&info, keydir, fit, image_name,
> - image_noffset, node_name, node_noffset);
> + image_noffset, node_noffset);
> if (ret)
> goto out;
> 
> @@ -482,7 +481,7 @@ int fit_image_cipher_data(const char *keydir, void 
> *keydest,
> const char *image_name;
> const void *data;
> size_t size;
> - int node_noffset;
> + int cipher_node_offset;
> 
> /* Get image name */
> image_name = fit_get_name(fit, image_noffset, NULL);
> @@ -497,32 +496,19 @@ int fit_image_cipher_data(const char *keydir, void
> *keydest,
> return -1;
> }
> 
> - /* Process all hash subnodes of the component image node */
> - for (node_noffset = fdt_first_subnode(fit, image_noffset);
> - node_noffset >= 0;
> - node_noffset = fdt_next_subnode(fit, node_noffset)) {
> - const char *node_name;
> - int ret = 0;
> -
> - node_name = fit_get_name(fit, node_noffset, NULL);
> - if (!node_name) {
> - printf("Can't get node name\n");
> - return -1;
> - }
> 
> - if (IMAGE_ENABLE_ENCRYPT && keydir &&
> - !strncmp(node_name, FIT_CIPHER_NODENAME,
> - strlen(FIT_CIPHER_NODENAME)))
> - ret = fit_image_process_cipher(keydir, keydest,
> - fit, image_name,
> - image_noffset,
> - node_name, node_noffset,
> - data, size, cmdname);
> - if (ret)
> - return ret;
> + /* Process cipher node if present */
> + cipher_node_offset = fdt_subnode_offset(fit, image_noffset, "cipher");

use FIT_CIPHER_NODENAME instead of hardcoded "cipher"

> + if (cipher_node_offset == -FDT_ERR_NOTFOUND)
> + return 0;
> + if (cipher_node_offset < 0) {
> + printf("Failure getting cipher node\n");
> + return -1;
> }
> -
> - return 0;
> + if (!IMAGE_ENABLE_ENCRYPT || !keydir)
> + return 0;
> + return fit_image_process_cipher(keydir, keydest, fit, image_name,
> + image_noffset, cipher_node_offset, data, size, cmdname);
> }
> 
> /**
> --
> 2.27.0


Other than this little remark:

Reviewed-by: Philippe Reynes 

Regards,
Philippe



Re: Improvements to FIT ciphering

2020-07-29 Thread Philippe REYNES


Hi Simon and Patrick,

Sorry, I've missed this serie of patches.
I check them and send a review ASAP.

Regards,
Philippe


> +Philippe Reynes too
> 
> 
> On Mon, 27 Jul 2020 at 16:50, Patrick Oppenlander
>  wrote:
>> 
>> On Fri, Jul 24, 2020 at 12:06 PM Patrick Oppenlander
>>  wrote:
>> > 
>> > Hi,
>> > 
>> > I recently posted some patches to the list [1], [2], [3] to address
>> > some issues with the cipher support in mkimage. Hopefully someone gets
>> > a chance to review these patches as I think mkimage is a bit broken
>> > without them.
>> > 
>> > While considering using U-Boot cipher support in a product I work on,
>> > I have convinced myself that the handling of the encryption IV could
>> > be better, especially given that mkimage is using AES-CBC mode.
>> > Please, correct me if I have missed something.
>> > 
>> > Issue #1
>> > 
>> > 
>> > Currently, mkimage treats the IV in the same manner as the encryption
>> > key. There is an iv-name-hint property which mkimage uses to read the
>> > IV from a file in the keys directory. This can then be written to
>> > u-boot.dtb along with the encryption key.
>> > 
>> > The problem with that is that u-boot.dtb is baked in at production
>> > time and is generally not field upgradable. That means that the IV is
>> > also baked in which is considered bad practice especially when using
>> > CBC mode (see CBC IV attack). In general it is my understanding that
>> > you should never use a key+IV twice regardless of cipher or mode.
>> > 
>> > In my opinion a better solution would have been to write the IV into
>> > the FIT image instead of iv-name-hint (it's only 16 bytes!), and
>> > regenerate it (/dev/random?) each and every time the data is ciphered.
>> > 
>> > An even better solution is to use AES-GCM (or something similar) as
>> > this includes the IV with the ciphertext, simplifying the above, and
>> > also provides authentication addressing another issue (see below).
>> > 
>> > Issue #2
>> > ===
>> > 
>> > The current implementation uses encrypt-then-sign. I like this
>> > approach as it means that the FIT image can be verified outside of
>> > U-Boot without requiring encryption keys. It is also considered best
>> > practise.
>> > 
>> > However, for this to be secure, the details of the cipher need to be
>> > included in the signature, otherwise an attacker can change the cipher
>> > or key/iv properties.
>> > 
>> > I do not believe that properties in the cipher node are currently
>> > included when signing a FIT configuration including an encrypted
>> > image. That should be a simple fix. Fixing it for image signatures
>> > might be a bit more tricky.
>> > 
>> > Issue #3
>> > ===
>> > 
>> > Due to the nature of encrypt-then-sign U-Boot can verify that the
>> > ciphertext is unmodified, but it has no way of making sure that the
>> > key used to encrypt the image matches the key in u-boot.fit used for
>> > decryption. This can result in an attempt to boot gibberish and I
>> > think it can open up certain attack vectors.
>> > 
>> > The best way I know of to fix this is to use an authenticated
>> > encryption mode such as AES-GCM or something similar.
>> > 
>> > 
>> > Kind regards,
>> > 
>> > Patrick
>> > 
>> > [1] https://lists.denx.de/pipermail/u-boot/2020-July/420399.html
>> > [2] https://lists.denx.de/pipermail/u-boot/2020-July/420400.html
>> > [3] https://lists.denx.de/pipermail/u-boot/2020-July/420401.html
>> 
>> Hi Simon,
>> 
>> I posted this writeup to the u-boot list and forgot to CC you. Sorry about 
>> that.
>> 
>> Patrick


Re: [PATCH v2 8/8] test: dm: add a test for class button

2020-07-24 Thread Philippe REYNES
Hi Simon,

> Hi Philippe,
> 
> On Mon, 20 Jul 2020 at 08:30, Philippe REYNES
>  wrote:
>> 
>> Hi Simon,
>> 
>> > Hi Philippe,
>> > 
>> > On Fri, 17 Jul 2020 at 06:22, Philippe Reynes
>> >  wrote:
>> >> 
>> >> Add a test to confirm that we can read button state
>> >> using the button-gpio driver.
>> >> 
>> >> Signed-off-by: Philippe Reynes 
>> >> ---
>> >> Changelog:
>> >> v2:
>> >> - new commit in the serie
>> >> 
>> >> test/dm/Makefile | 1 +
>> >> test/dm/button.c | 74 
>> >> 
>> >> 2 files changed, 75 insertions(+)
>> >> create mode 100644 test/dm/button.c
>> > 
>> > This seems to fail with 'make qcheck'. Can you please take a look?
>> > I've left it unapplied for now.
>> 
>> I've tried to reproduce this issue, but make qcheck don't work for me.
>> I have some issues with test for binman, patman, and dtoc.
>> 
>> Could you provide me the log of the issue with 'make qcheck' please ?
> 
> See below. What sort of issues are you seeing? I wonder if we should
> have a script to set up for running these tests fully.
> 
> 
> === FAILURES
> ===
> __
> test_button_exit_statuses
> ___
> 
> u_boot_console =  0x7fe1121eef60>
> 
> @pytest.mark.boardspec('sandbox')
> @pytest.mark.buildconfigspec('cmd_button')
> def test_button_exit_statuses(u_boot_console):
> """Test that non-input button commands correctly return the command
> success/failure status."""
> 
> expected_response = 'rc:0'
> response = u_boot_console.run_command('button list; echo rc:$?')
> assert(expected_response in response)
> response = u_boot_console.run_command('button summer; echo rc:$?')
>> assert(expected_response in response)
> E assert 'rc:0' in "Button 'summer' not found (err=-16)\r\r\nrc:1"
> 
> test/py/tests/test_button.py:15: AssertionError
> - Captured stdout call
> -
> => button list; echo rc:$?
> summer 
> christmas 
> rc:0
> => => button summer; echo rc:$?
> Button 'summer' not found (err=-16)
> rc:1
> =>
> == 1 failed, 512 passed, 59 skipped, 105
> deselected in 43.38s ==


I think I have found the issue. This issue only appears after the commit
9ba84329dc45 ("sandbox, test: add test for GPIO_HOG function") that uses
gpio_a 0, 1, 2 and 3.

I've sent a patch do change the gpio used for hog on sandbox. With this
patch, I don't reproduce this issue.

> Regards,
> Simon

Regards,
Philippe


[PATCH v3 3/8] cmd: button: add a new 'button' command

2020-07-24 Thread Philippe Reynes
Adds a command 'button' that provides the list of buttons
supported by the board, and the state of a button.

Reviewed-by: Simon Glass 
Signed-off-by: Philippe Reynes 
---
Changelog:
v3:
- no change
v2
- no change

 cmd/Kconfig  | 11 
 cmd/Makefile |  1 +
 cmd/button.c | 86 
 3 files changed, 98 insertions(+)
 create mode 100644 cmd/button.c

diff --git a/cmd/Kconfig b/cmd/Kconfig
index bfe6c16..8ef87dc 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -1679,6 +1679,17 @@ config CMD_BLOCK_CACHE
  during development, but also allows the cache to be disabled when
  it might hurt performance (e.g. when using the ums command).
 
+config CMD_BUTTON
+   bool "button"
+   depends on BUTTON
+   default y if BUTTON
+   help
+ Enable the 'button' command which allows to get the status of
+ buttons supported by the board. The buttonss can be listed with
+ 'button list' and state can be known with 'button '.
+ Any button drivers can be controlled with this command, e.g.
+ button_gpio.
+
 config CMD_CACHE
bool "icache or dcache"
help
diff --git a/cmd/Makefile b/cmd/Makefile
index 7952138..6e0086b 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_CMD_BOOTSTAGE) += bootstage.o
 obj-$(CONFIG_CMD_BOOTZ) += bootz.o
 obj-$(CONFIG_CMD_BOOTI) += booti.o
 obj-$(CONFIG_CMD_BTRFS) += btrfs.o
+obj-$(CONFIG_CMD_BUTTON) += button.o
 obj-$(CONFIG_CMD_CACHE) += cache.o
 obj-$(CONFIG_CMD_CBFS) += cbfs.o
 obj-$(CONFIG_CMD_CLK) += clk.o
diff --git a/cmd/button.c b/cmd/button.c
new file mode 100644
index 000..84ad165
--- /dev/null
+++ b/cmd/button.c
@@ -0,0 +1,86 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 Philippe Reynes 
+ *
+ * Based on led.c
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static const char *const state_label[] = {
+   [BUTTON_OFF]= "off",
+   [BUTTON_ON] = "on",
+};
+
+static int show_button_state(struct udevice *dev)
+{
+   int ret;
+
+   ret = button_get_state(dev);
+   if (ret >= BUTTON_COUNT)
+   ret = -EINVAL;
+   if (ret >= 0)
+   printf("%s\n", state_label[ret]);
+
+   return ret;
+}
+
+static int list_buttons(void)
+{
+   struct udevice *dev;
+   int ret;
+
+   for (uclass_find_first_device(UCLASS_BUTTON, &dev);
+dev;
+uclass_find_next_device(&dev)) {
+   struct button_uc_plat *plat = dev_get_uclass_platdata(dev);
+
+   if (!plat->label)
+   continue;
+   printf("%-15s ", plat->label);
+   if (device_active(dev)) {
+   ret = show_button_state(dev);
+   if (ret < 0)
+   printf("Error %d\n", ret);
+   } else {
+   printf("\n");
+   }
+   }
+
+   return 0;
+}
+
+int do_button(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
+{
+   const char *button_label;
+   struct udevice *dev;
+   int ret;
+
+   /* Validate arguments */
+   if (argc < 2)
+   return CMD_RET_USAGE;
+   button_label = argv[1];
+   if (strncmp(button_label, "list", 4) == 0)
+   return list_buttons();
+
+   ret = button_get_by_label(button_label, &dev);
+   if (ret) {
+   printf("Button '%s' not found (err=%d)\n", button_label, ret);
+   return CMD_RET_FAILURE;
+   }
+
+   ret = show_button_state(dev);
+
+   return 0;
+}
+
+U_BOOT_CMD(
+   button, 4, 1, do_button,
+   "manage buttons",
+   " \tGet button state\n"
+   "button list\t\tShow a list of buttons"
+);
-- 
2.7.4



[PATCH v3 8/8] test: dm: add a test for class button

2020-07-24 Thread Philippe Reynes
Add a test to confirm that we can read button state
using the button-gpio driver.

Signed-off-by: Philippe Reynes 
---
Changelog:
v3:
- no change
v2:
- new commit in the serie

 test/dm/Makefile |  1 +
 test/dm/button.c | 74 
 2 files changed, 75 insertions(+)
 create mode 100644 test/dm/button.c

diff --git a/test/dm/Makefile b/test/dm/Makefile
index b03c96d..42b46cc 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_ACPIGEN) += acpi_dp.o
 obj-$(CONFIG_SOUND) += audio.o
 obj-$(CONFIG_BLK) += blk.o
 obj-$(CONFIG_BOARD) += board.o
+obj-$(CONFIG_BUTTON) += button.o
 obj-$(CONFIG_DM_BOOTCOUNT) += bootcount.o
 obj-$(CONFIG_CLK) += clk.o clk_ccf.o
 obj-$(CONFIG_DEVRES) += devres.o
diff --git a/test/dm/button.c b/test/dm/button.c
new file mode 100644
index 000..890f470
--- /dev/null
+++ b/test/dm/button.c
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 Philippe Reynes 
+ *
+ * Based on led.c
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* Base test of the button uclass */
+static int dm_test_button_base(struct unit_test_state *uts)
+{
+   struct udevice *dev;
+
+   /* Get the top-level device */
+   ut_assertok(uclass_get_device(UCLASS_BUTTON, 0, &dev));
+   ut_assertok(uclass_get_device(UCLASS_BUTTON, 1, &dev));
+   ut_assertok(uclass_get_device(UCLASS_BUTTON, 2, &dev));
+   ut_asserteq(-ENODEV, uclass_get_device(UCLASS_BUTTON, 3, &dev));
+
+   return 0;
+}
+DM_TEST(dm_test_button_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test of the button uclass using the button_gpio driver */
+static int dm_test_button_gpio(struct unit_test_state *uts)
+{
+   const int offset = 3;
+   struct udevice *dev, *gpio;
+
+   /*
+* Check that we can manipulate an BUTTON. BUTTON 1 is connected to GPIO
+* bank gpio_a, offset 3.
+*/
+   ut_assertok(uclass_get_device(UCLASS_BUTTON, 1, &dev));
+   ut_assertok(uclass_get_device(UCLASS_GPIO, 1, &gpio));
+
+   ut_asserteq(0, sandbox_gpio_set_value(gpio, offset, 0));
+   ut_asserteq(0, sandbox_gpio_get_value(gpio, offset));
+   ut_asserteq(BUTTON_OFF, button_get_state(dev));
+
+   ut_asserteq(0, sandbox_gpio_set_value(gpio, offset, 1));
+   ut_asserteq(1, sandbox_gpio_get_value(gpio, offset));
+   ut_asserteq(BUTTON_ON, button_get_state(dev));
+
+   return 0;
+}
+DM_TEST(dm_test_button_gpio, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test obtaining an BUTTON by label */
+static int dm_test_button_label(struct unit_test_state *uts)
+{
+   struct udevice *dev, *cmp;
+
+   ut_assertok(button_get_by_label("summer", &dev));
+   ut_asserteq(1, device_active(dev));
+   ut_assertok(uclass_get_device(UCLASS_BUTTON, 1, &cmp));
+   ut_asserteq_ptr(dev, cmp);
+
+   ut_assertok(button_get_by_label("christmas", &dev));
+   ut_asserteq(1, device_active(dev));
+   ut_assertok(uclass_get_device(UCLASS_BUTTON, 2, &cmp));
+   ut_asserteq_ptr(dev, cmp);
+
+   ut_asserteq(-ENODEV, button_get_by_label("spring", &dev));
+
+   return 0;
+}
+DM_TEST(dm_test_button_label, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
-- 
2.7.4



[PATCH v3 6/8] sandbox: enable button

2020-07-24 Thread Philippe Reynes
Enable the support of button (driver and command) on sandbox.

Reviewed-by: Simon Glass 
Signed-off-by: Philippe Reynes 
---
Changelog:
v3:
- no change
v2:
- no change

 configs/sandbox_defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 6059d66..18cecf5 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -106,6 +106,8 @@ CONFIG_AXI_SANDBOX=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_DM_BOOTCOUNT=y
 CONFIG_DM_BOOTCOUNT_RTC=y
+CONFIG_BUTTON=y
+CONFIG_BUTTON_GPIO=y
 CONFIG_CLK=y
 CONFIG_CLK_COMPOSITE_CCF=y
 CONFIG_SANDBOX_CLK_CCF=y
-- 
2.7.4



[PATCH v3 4/8] sandbox: dtsi: add buttons

2020-07-24 Thread Philippe Reynes
Adds two buttons on sandbox so button framework may be tested.

Reviewed-by: Simon Glass 
Signed-off-by: Philippe Reynes 
---
Changelog:
v3:
- update comptatible to "gpio-keys"
v2:
- no change

 arch/sandbox/dts/sandbox.dtsi | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/arch/sandbox/dts/sandbox.dtsi b/arch/sandbox/dts/sandbox.dtsi
index e1f68cd..c76ecc0 100644
--- a/arch/sandbox/dts/sandbox.dtsi
+++ b/arch/sandbox/dts/sandbox.dtsi
@@ -15,6 +15,20 @@
#sound-dai-cells = <1>;
};
 
+   buttons {
+   compatible = "gpio-keys";
+
+   summer {
+   gpios = <&gpio_a 3 0>;
+   label = "summer";
+   };
+
+   christmas {
+   gpios = <&gpio_a 4 0>;
+   label = "christmas";
+   };
+   };
+
gpio_a: gpios@0 {
u-boot,dm-pre-reloc;
gpio-controller;
-- 
2.7.4



[PATCH v3 2/8] dm: button: add a driver for button driven by gpio

2020-07-24 Thread Philippe Reynes
Add a simple driver which allows use of buttons attached to GPIOs.

Reviewed-by: Simon Glass 
Signed-off-by: Philippe Reynes 
---
Changelog:
v3:
- change compatible to gpio-keys and gpio-keys-polled
  (feedback from Neil Armstrong)
v2:
- remove useless default in Kconfig
- re-order include
- fix condition in button_gpio_remove

 drivers/button/Kconfig   |   9 
 drivers/button/Makefile  |   1 +
 drivers/button/button-gpio.c | 112 +++
 3 files changed, 122 insertions(+)
 create mode 100644 drivers/button/button-gpio.c

diff --git a/drivers/button/Kconfig b/drivers/button/Kconfig
index 8301858..6b3ec7e 100644
--- a/drivers/button/Kconfig
+++ b/drivers/button/Kconfig
@@ -9,4 +9,13 @@ config BUTTON
  can provide access to board-specific buttons. Use of the device tree
  for configuration is encouraged.
 
+config BUTTON_GPIO
+   bool "Button gpio"
+   depends on BUTTON
+   help
+ Enable support for buttons which are connected to GPIO lines. These
+ GPIOs may be on the SoC or some other device which provides GPIOs.
+ The GPIO driver must used driver model. Buttons are configured using
+ the device tree.
+
 endmenu
diff --git a/drivers/button/Makefile b/drivers/button/Makefile
index 0b4c128..fcc10eb 100644
--- a/drivers/button/Makefile
+++ b/drivers/button/Makefile
@@ -3,3 +3,4 @@
 # Copyright (C) 2020 Philippe Reynes 
 
 obj-$(CONFIG_BUTTON) += button-uclass.o
+obj-$(CONFIG_BUTTON_GPIO) += button-gpio.o
diff --git a/drivers/button/button-gpio.c b/drivers/button/button-gpio.c
new file mode 100644
index 000..985ae7f
--- /dev/null
+++ b/drivers/button/button-gpio.c
@@ -0,0 +1,112 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 Philippe Reynes 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct button_gpio_priv {
+   struct gpio_desc gpio;
+};
+
+static enum button_state_t button_gpio_get_state(struct udevice *dev)
+{
+   struct button_gpio_priv *priv = dev_get_priv(dev);
+   int ret;
+
+   if (!dm_gpio_is_valid(&priv->gpio))
+   return -EREMOTEIO;
+   ret = dm_gpio_get_value(&priv->gpio);
+   if (ret < 0)
+   return ret;
+
+   return ret ? BUTTON_ON : BUTTON_OFF;
+}
+
+static int button_gpio_probe(struct udevice *dev)
+{
+   struct button_uc_plat *uc_plat = dev_get_uclass_platdata(dev);
+   struct button_gpio_priv *priv = dev_get_priv(dev);
+   int ret;
+
+   /* Ignore the top-level button node */
+   if (!uc_plat->label)
+   return 0;
+
+   ret = gpio_request_by_name(dev, "gpios", 0, &priv->gpio, GPIOD_IS_IN);
+   if (ret)
+   return ret;
+
+   return 0;
+}
+
+static int button_gpio_remove(struct udevice *dev)
+{
+   /*
+* The GPIO driver may have already been removed. We will need to
+* address this more generally.
+*/
+   if (!IS_ENABLED(CONFIG_SANDBOX)) {
+   struct button_gpio_priv *priv = dev_get_priv(dev);
+
+   if (dm_gpio_is_valid(&priv->gpio))
+   dm_gpio_free(dev, &priv->gpio);
+   }
+
+   return 0;
+}
+
+static int button_gpio_bind(struct udevice *parent)
+{
+   struct udevice *dev;
+   ofnode node;
+   int ret;
+
+   dev_for_each_subnode(node, parent) {
+   struct button_uc_plat *uc_plat;
+   const char *label;
+
+   label = ofnode_read_string(node, "label");
+   if (!label) {
+   debug("%s: node %s has no label\n", __func__,
+ ofnode_get_name(node));
+   return -EINVAL;
+   }
+   ret = device_bind_driver_to_node(parent, "button_gpio",
+ofnode_get_name(node),
+node, &dev);
+   if (ret)
+   return ret;
+   uc_plat = dev_get_uclass_platdata(dev);
+   uc_plat->label = label;
+   }
+
+   return 0;
+}
+
+static const struct button_ops button_gpio_ops = {
+   .get_state  = button_gpio_get_state,
+};
+
+static const struct udevice_id button_gpio_ids[] = {
+   { .compatible = "gpio-keys" },
+   { .compatible = "gpio-keys-polled" },
+   { }
+};
+
+U_BOOT_DRIVER(button_gpio) = {
+   .name   = "button_gpio",
+   .id = UCLASS_BUTTON,
+   .of_match   = button_gpio_ids,
+   .ops= &button_gpio_ops,
+   .priv_auto_alloc_size = sizeof(struct button_gpio_priv),
+   .bind   = button_gpio_bind,
+   .probe  = button_gpio_probe,
+   .remove = button_gpio_remove,
+};
-- 
2.7.4



[PATCH v3 1/8] dm: button: add an uclass for button

2020-07-24 Thread Philippe Reynes
Add a new uclass for button that implements two functions:
- button_get_by_label
- button_get_status

Reviewed-by: Simon Glass 
Signed-off-by: Philippe Reynes 
---

Changelog:
v3:
- no change
v2:
- re-order include
- use uclass_id_foreach_dev
- add comments to enum button_state_t

 drivers/Kconfig|  2 ++
 drivers/Makefile   |  1 +
 drivers/button/Kconfig | 12 +
 drivers/button/Makefile|  5 
 drivers/button/button-uclass.c | 43 ++
 include/button.h   | 59 ++
 include/dm/uclass-id.h |  1 +
 7 files changed, 123 insertions(+)
 create mode 100644 drivers/button/Kconfig
 create mode 100644 drivers/button/Makefile
 create mode 100644 drivers/button/button-uclass.c
 create mode 100644 include/button.h

diff --git a/drivers/Kconfig b/drivers/Kconfig
index 7a839fa..119e412 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -16,6 +16,8 @@ source "drivers/block/Kconfig"
 
 source "drivers/bootcount/Kconfig"
 
+source "drivers/button/Kconfig"
+
 source "drivers/cache/Kconfig"
 
 source "drivers/clk/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index afd159e..2178871 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0+
 
+obj-$(CONFIG_$(SPL_TPL_)BUTTON) += button/
 obj-$(CONFIG_$(SPL_TPL_)CACHE) += cache/
 obj-$(CONFIG_$(SPL_TPL_)CLK) += clk/
 obj-$(CONFIG_$(SPL_TPL_)DM) += core/
diff --git a/drivers/button/Kconfig b/drivers/button/Kconfig
new file mode 100644
index 000..8301858
--- /dev/null
+++ b/drivers/button/Kconfig
@@ -0,0 +1,12 @@
+menu "Button Support"
+
+config BUTTON
+   bool "Enable button support"
+   depends on DM
+   help
+ Many boards have buttons which can be used to change behaviour 
(reset, ...).
+ U-Boot provides a uclass API to implement this feature. Button drivers
+ can provide access to board-specific buttons. Use of the device tree
+ for configuration is encouraged.
+
+endmenu
diff --git a/drivers/button/Makefile b/drivers/button/Makefile
new file mode 100644
index 000..0b4c128
--- /dev/null
+++ b/drivers/button/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2020 Philippe Reynes 
+
+obj-$(CONFIG_BUTTON) += button-uclass.o
diff --git a/drivers/button/button-uclass.c b/drivers/button/button-uclass.c
new file mode 100644
index 000..1c742c2
--- /dev/null
+++ b/drivers/button/button-uclass.c
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 Philippe Reynes 
+ *
+ * Based on led-uclass.c
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+int button_get_by_label(const char *label, struct udevice **devp)
+{
+   struct udevice *dev;
+   struct uclass *uc;
+
+   uclass_id_foreach_dev(UCLASS_BUTTON, dev, uc) {
+   struct button_uc_plat *uc_plat = dev_get_uclass_platdata(dev);
+
+   /* Ignore the top-level button node */
+   if (uc_plat->label && !strcmp(label, uc_plat->label))
+   return uclass_get_device_tail(dev, 0, devp);
+   }
+
+   return -ENODEV;
+}
+
+enum button_state_t button_get_state(struct udevice *dev)
+{
+   struct button_ops *ops = button_get_ops(dev);
+
+   if (!ops->get_state)
+   return -ENOSYS;
+
+   return ops->get_state(dev);
+}
+
+UCLASS_DRIVER(button) = {
+   .id = UCLASS_BUTTON,
+   .name   = "button",
+   .per_device_platdata_auto_alloc_size = sizeof(struct button_uc_plat),
+};
diff --git a/include/button.h b/include/button.h
new file mode 100644
index 000..688b63b
--- /dev/null
+++ b/include/button.h
@@ -0,0 +1,59 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2020 Philippe Reynes 
+ */
+
+#ifndef __BUTTON_H
+#define __BUTTON_H
+
+/**
+ * struct button_uc_plat - Platform data the uclass stores about each device
+ *
+ * @label: Button label
+ */
+struct button_uc_plat {
+   const char *label;
+};
+
+/**
+ * enum button_state_t - State used for button
+ * - BUTTON_OFF - Button is not pressed
+ * - BUTTON_ON - Button is pressed
+ * - BUTTON_COUNT - Number of button state
+ */
+enum button_state_t {
+   BUTTON_OFF = 0,
+   BUTTON_ON = 1,
+   BUTTON_COUNT,
+};
+
+struct button_ops {
+   /**
+* get_state() - get the state of a button
+*
+* @dev:button device to change
+* @return button state button_state_t, or -ve on error
+*/
+   enum button_state_t (*get_state)(struct udevice *dev);
+};
+
+#define button_get_ops(dev)((struct button_ops *)(dev)->driver->ops)
+
+/**
+ * button_get_by_label() - Find a button device by label
+ *
+ * @label: button label to look up
+ * @devp:  Returns the associated device, if 

[PATCH v3 7/8] test/py: add tests for the button commands

2020-07-24 Thread Philippe Reynes
Adds tests for the button commands.

Reviewed-by: Simon Glass 
Signed-off-by: Philippe Reynes 
---
Changelog:
v3:
- update compatible to "gpio-keys"
v2:
- no change (button uclass test is added in another commit

 arch/sandbox/dts/test.dts| 14 ++
 test/py/tests/test_button.py | 19 +++
 2 files changed, 33 insertions(+)
 create mode 100644 test/py/tests/test_button.py

diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index c3404c0..db8fa54 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -51,6 +51,20 @@
#sound-dai-cells = <1>;
};
 
+   buttons {
+   compatible = "gpio-keys";
+
+   summer {
+   gpios = <&gpio_a 3 0>;
+   label = "summer";
+   };
+
+   christmas {
+   gpios = <&gpio_a 4 0>;
+   label = "christmas";
+   };
+   };
+
cros_ec: cros-ec {
reg = <0 0>;
compatible = "google,cros-ec-sandbox";
diff --git a/test/py/tests/test_button.py b/test/py/tests/test_button.py
new file mode 100644
index 000..98067a9
--- /dev/null
+++ b/test/py/tests/test_button.py
@@ -0,0 +1,19 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+import pytest
+
+@pytest.mark.boardspec('sandbox')
+@pytest.mark.buildconfigspec('cmd_button')
+def test_button_exit_statuses(u_boot_console):
+"""Test that non-input button commands correctly return the command
+success/failure status."""
+
+expected_response = 'rc:0'
+response = u_boot_console.run_command('button list; echo rc:$?')
+assert(expected_response in response)
+response = u_boot_console.run_command('button summer; echo rc:$?')
+assert(expected_response in response)
+
+expected_response = 'rc:1'
+response = u_boot_console.run_command('button nonexistent-button; echo 
rc:$?')
+assert(expected_response in response)
-- 
2.7.4



[PATCH v3 5/8] sandbox64: enable button

2020-07-24 Thread Philippe Reynes
Enable the support of button (driver and command) on sandbox64.

Reviewed-by: Simon Glass 
Signed-off-by: Philippe Reynes 
---
Changelog:
v3:
- no change
v2:
- no change

 configs/sandbox64_defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig
index dcf2f44..875a9dc 100644
--- a/configs/sandbox64_defconfig
+++ b/configs/sandbox64_defconfig
@@ -92,6 +92,8 @@ CONFIG_ADC=y
 CONFIG_ADC_SANDBOX=y
 CONFIG_AXI=y
 CONFIG_AXI_SANDBOX=y
+CONFIG_BUTTON=y
+CONFIG_BUTTON_GPIO=y
 CONFIG_CLK=y
 CONFIG_CPU=y
 CONFIG_DM_DEMO=y
-- 
2.7.4



[PATCH] sandbox, test: change hog gpio

2020-07-24 Thread Philippe Reynes
Since commit 9ba84329dc45 ("sandbox, test: add test for GPIO_HOG
function"), the gpio_a 0,1,2 and 3 are used by hog in test.dts.
But 2 leds 'sandbox:red' and 'sandbox:green' are using gpio_a 0
and 1. As hog always request his gpios, the led command on both
led is broken:

=> led sandbox:red
LED 'sandbox:red' not found (err=-16)

The gpio is already requested by hog, so it can't be enabled
for led 'sandbox:red'.

This commit change the gpio used by hog to 10, 11, 12 and 13,
so the led command could be used again with 'sandbox:red' and
'sandbox:green'.

Signed-off-by: Philippe Reynes 
---
 arch/sandbox/dts/test.dts |  8 
 test/dm/gpio.c| 12 ++--
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 2ae4239..2325ec6 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -355,22 +355,22 @@
hog_input_active_low {
gpio-hog;
input;
-   gpios = <0 GPIO_ACTIVE_LOW>;
+   gpios = <10 GPIO_ACTIVE_LOW>;
};
hog_input_active_high {
gpio-hog;
input;
-   gpios = <1 GPIO_ACTIVE_HIGH>;
+   gpios = <11 GPIO_ACTIVE_HIGH>;
};
hog_output_low {
gpio-hog;
output-low;
-   gpios = <2 GPIO_ACTIVE_HIGH>;
+   gpios = <12 GPIO_ACTIVE_HIGH>;
};
hog_output_high {
gpio-hog;
output-high;
-   gpios = <3 GPIO_ACTIVE_HIGH>;
+   gpios = <13 GPIO_ACTIVE_HIGH>;
};
};
 
diff --git a/test/dm/gpio.c b/test/dm/gpio.c
index 2970138..b7ee8fc 100644
--- a/test/dm/gpio.c
+++ b/test/dm/gpio.c
@@ -114,21 +114,21 @@ static int dm_test_gpio(struct unit_test_state *uts)
/* add gpio hog tests */
ut_assertok(gpio_hog_lookup_name("hog_input_active_low", &desc));
ut_asserteq(GPIOD_IS_IN | GPIOD_ACTIVE_LOW, desc->flags);
-   ut_asserteq(0, desc->offset);
+   ut_asserteq(10, desc->offset);
ut_asserteq(1, dm_gpio_get_value(desc));
ut_assertok(gpio_hog_lookup_name("hog_input_active_high", &desc));
ut_asserteq(GPIOD_IS_IN, desc->flags);
-   ut_asserteq(1, desc->offset);
+   ut_asserteq(11, desc->offset);
ut_asserteq(0, dm_gpio_get_value(desc));
ut_assertok(gpio_hog_lookup_name("hog_output_low", &desc));
ut_asserteq(GPIOD_IS_OUT, desc->flags);
-   ut_asserteq(2, desc->offset);
+   ut_asserteq(12, desc->offset);
ut_asserteq(0, dm_gpio_get_value(desc));
ut_assertok(dm_gpio_set_value(desc, 1));
ut_asserteq(1, dm_gpio_get_value(desc));
ut_assertok(gpio_hog_lookup_name("hog_output_high", &desc));
ut_asserteq(GPIOD_IS_OUT, desc->flags);
-   ut_asserteq(3, desc->offset);
+   ut_asserteq(13, desc->offset);
ut_asserteq(1, dm_gpio_get_value(desc));
ut_assertok(dm_gpio_set_value(desc, 0));
ut_asserteq(0, dm_gpio_get_value(desc));
@@ -137,8 +137,8 @@ static int dm_test_gpio(struct unit_test_state *uts)
ut_assertok(gpio_lookup_name("hog_input_active_low", &dev, &offset,
 &gpio));
ut_asserteq_str(dev->name, "base-gpios");
-   ut_asserteq(0, offset);
-   ut_asserteq(CONFIG_SANDBOX_GPIO_COUNT + 0, gpio);
+   ut_asserteq(10, offset);
+   ut_asserteq(CONFIG_SANDBOX_GPIO_COUNT + 10, gpio);
ut_assert(gpio_lookup_name("hog_not_exist", &dev, &offset,
   &gpio));
 
-- 
2.7.4



Re: [PATCH v2 8/8] test: dm: add a test for class button

2020-07-20 Thread Philippe REYNES
Hi Simon,

> Hi Philippe,
> 
> On Fri, 17 Jul 2020 at 06:22, Philippe Reynes
>  wrote:
>> 
>> Add a test to confirm that we can read button state
>> using the button-gpio driver.
>> 
>> Signed-off-by: Philippe Reynes 
>> ---
>> Changelog:
>> v2:
>> - new commit in the serie
>> 
>> test/dm/Makefile | 1 +
>> test/dm/button.c | 74 
>> 
>> 2 files changed, 75 insertions(+)
>> create mode 100644 test/dm/button.c
> 
> This seems to fail with 'make qcheck'. Can you please take a look?
> I've left it unapplied for now.

I've tried to reproduce this issue, but make qcheck don't work for me.
I have some issues with test for binman, patman, and dtoc.

Could you provide me the log of the issue with 'make qcheck' please ?

 
> Regards,
> Simon


Regards,
Philippe


Re: [PATCH 1/1] test/dm: check if devices exist

2020-07-17 Thread Philippe REYNES
Hi Heinrich

> Running 'ut dm' on the sandbox without -D or -d results in segmentation
> faults due to NULL pointer dereferences.
> 
> Check that device pointers are non-NULL before using them.
> 
> Use ut_assertnonnull() for pointers instead of ut_assert().

Tested-by: Philippe Reynes 

> Signed-off-by: Heinrich Schuchardt 
> ---
> test/dm/acpi.c | 3 +++
> test/dm/core.c | 10 +-
> test/dm/devres.c | 1 +
> test/dm/test-fdt.c | 2 ++
> test/dm/virtio.c | 7 +++
> 5 files changed, 18 insertions(+), 5 deletions(-)
> 
> diff --git a/test/dm/acpi.c b/test/dm/acpi.c
> index 4c46dd83a6..ece7993cf3 100644
> --- a/test/dm/acpi.c
> +++ b/test/dm/acpi.c
> @@ -96,7 +96,10 @@ DM_TEST(dm_test_acpi_get_table_revision,
> static int dm_test_acpi_create_dmar(struct unit_test_state *uts)
> {
> struct acpi_dmar dmar;
> + struct udevice *cpu;
> 
> + ut_assertok(uclass_first_device(UCLASS_CPU, &cpu));
> + ut_assertnonnull(cpu);
> ut_assertok(acpi_create_dmar(&dmar, DMAR_INTR_REMAP));
> ut_asserteq(DMAR_INTR_REMAP, dmar.flags);
> ut_asserteq(32 - 1, dmar.host_address_width);
> diff --git a/test/dm/core.c b/test/dm/core.c
> index 6a930ae31a..d20c48443f 100644
> --- a/test/dm/core.c
> +++ b/test/dm/core.c
> @@ -158,7 +158,7 @@ static int dm_test_autobind_uclass_pdata_alloc(struct
> unit_test_state *uts)
> for (uclass_find_first_device(UCLASS_TEST, &dev);
> dev;
> uclass_find_next_device(&dev)) {
> - ut_assert(dev);
> + ut_assertnonnull(dev);
> 
> uc_pdata = dev_get_uclass_platdata(dev);
> ut_assert(uc_pdata);
> @@ -181,7 +181,7 @@ static int dm_test_autobind_uclass_pdata_valid(struct
> unit_test_state *uts)
> for (uclass_find_first_device(UCLASS_TEST, &dev);
> dev;
> uclass_find_next_device(&dev)) {
> - ut_assert(dev);
> + ut_assertnonnull(dev);
> 
> uc_pdata = dev_get_uclass_platdata(dev);
> ut_assert(uc_pdata);
> @@ -747,11 +747,11 @@ static int dm_test_uclass_devices_find(struct
> unit_test_state *uts)
> dev;
> ret = uclass_find_next_device(&dev)) {
> ut_assert(!ret);
> - ut_assert(dev);
> + ut_assertnonnull(dev);
> }
> 
> ut_assertok(uclass_find_first_device(UCLASS_TEST_DUMMY, &dev));
> - ut_assert(!dev);
> + ut_assertnull(dev);
> 
> return 0;
> }
> @@ -778,7 +778,7 @@ static int dm_test_uclass_devices_find_by_name(struct
> unit_test_state *uts)
> testdev;
> ret = uclass_find_next_device(&testdev)) {
> ut_assertok(ret);
> - ut_assert(testdev);
> + ut_assertnonnull(testdev);
> 
> findret = uclass_find_device_by_name(UCLASS_TEST_FDT,
> testdev->name,
> diff --git a/test/dm/devres.c b/test/dm/devres.c
> index b5de0cb191..550787495d 100644
> --- a/test/dm/devres.c
> +++ b/test/dm/devres.c
> @@ -153,6 +153,7 @@ static int dm_test_devres_phase(struct unit_test_state 
> *uts)
> * allocation created in the bind() method.
> */
> ut_assertok(uclass_find_first_device(UCLASS_TEST_DEVRES, &dev));
> + ut_assertnonnull(dev);
> devres_get_stats(dev, &stats);
> ut_asserteq(1, stats.allocs);
> ut_asserteq(TEST_DEVRES_SIZE, stats.total_size);
> diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c
> index 51f2547409..8ef7c7a88e 100644
> --- a/test/dm/test-fdt.c
> +++ b/test/dm/test-fdt.c
> @@ -832,10 +832,12 @@ static int dm_test_fdt_phandle(struct unit_test_state
> *uts)
> struct udevice *back, *dev, *dev2;
> 
> ut_assertok(uclass_find_first_device(UCLASS_PANEL_BACKLIGHT, &back));
> + ut_assertnonnull(back);
> ut_asserteq(-ENOENT, uclass_find_device_by_phandle(UCLASS_REGULATOR,
> back, "missing", &dev));
> ut_assertok(uclass_find_device_by_phandle(UCLASS_REGULATOR, back,
> "power-supply", &dev));
> + ut_assertnonnull(dev);
> ut_asserteq(0, device_active(dev));
> ut_asserteq_str("ldo1", dev->name);
> ut_assertok(uclass_get_device_by_phandle(UCLASS_REGULATOR, back,
> diff --git a/test/dm/virtio.c b/test/dm/virtio.c
> index 4b317d2ec3..4a0c0b23b8 100644
> --- a/test/dm/virtio.c
> +++ b/test/dm/virtio.c
> @@ -22,9 +22,11 @@ static int dm_test_virtio_base(struct unit_test_state *uts)
> 
> /* check probe success */
> ut_assertok(uclass_first_device(UCLASS_VIRTIO, &bus));
> + ut_assertnonnull(bus);
> 
> /* check the child virtio-blk device is bound */
> ut_assertok(device_find_first_child(bus, &dev));
> + ut_assertnonnull(dev);
> ut_assertok(strcmp(dev->name, "virtio-blk#0"));
> 
> /* check driver status */
> @@ -49,15 +51,18 @@ static int dm_test_virtio_all_ops(struct unit_test_state
> *uts)
> 
> /* check probe success */
> ut_assertok(uclass_first_device(UCLASS_VIRTIO, &bus));
> + ut_assertnonnull(bus);
> 
> 

[PATCH v2 3/8] cmd: button: add a new 'button' command

2020-07-17 Thread Philippe Reynes
Adds a command 'button' that provides the list of buttons
supported by the board, and the state of a button.

Reviewed-by: Simon Glass 
Signed-off-by: Philippe Reynes 
---
Changelog:
v2
- no change

 cmd/Kconfig  | 11 
 cmd/Makefile |  1 +
 cmd/button.c | 86 
 3 files changed, 98 insertions(+)
 create mode 100644 cmd/button.c

diff --git a/cmd/Kconfig b/cmd/Kconfig
index 192b3b2..750d26a 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -1664,6 +1664,17 @@ config CMD_BLOCK_CACHE
  during development, but also allows the cache to be disabled when
  it might hurt performance (e.g. when using the ums command).
 
+config CMD_BUTTON
+   bool "button"
+   depends on BUTTON
+   default y if BUTTON
+   help
+ Enable the 'button' command which allows to get the status of
+ buttons supported by the board. The buttonss can be listed with
+ 'button list' and state can be known with 'button '.
+ Any button drivers can be controlled with this command, e.g.
+ button_gpio.
+
 config CMD_CACHE
bool "icache or dcache"
help
diff --git a/cmd/Makefile b/cmd/Makefile
index 974ad48..5ded3a6 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_CMD_BOOTSTAGE) += bootstage.o
 obj-$(CONFIG_CMD_BOOTZ) += bootz.o
 obj-$(CONFIG_CMD_BOOTI) += booti.o
 obj-$(CONFIG_CMD_BTRFS) += btrfs.o
+obj-$(CONFIG_CMD_BUTTON) += button.o
 obj-$(CONFIG_CMD_CACHE) += cache.o
 obj-$(CONFIG_CMD_CBFS) += cbfs.o
 obj-$(CONFIG_CMD_CLK) += clk.o
diff --git a/cmd/button.c b/cmd/button.c
new file mode 100644
index 000..84ad165
--- /dev/null
+++ b/cmd/button.c
@@ -0,0 +1,86 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 Philippe Reynes 
+ *
+ * Based on led.c
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static const char *const state_label[] = {
+   [BUTTON_OFF]= "off",
+   [BUTTON_ON] = "on",
+};
+
+static int show_button_state(struct udevice *dev)
+{
+   int ret;
+
+   ret = button_get_state(dev);
+   if (ret >= BUTTON_COUNT)
+   ret = -EINVAL;
+   if (ret >= 0)
+   printf("%s\n", state_label[ret]);
+
+   return ret;
+}
+
+static int list_buttons(void)
+{
+   struct udevice *dev;
+   int ret;
+
+   for (uclass_find_first_device(UCLASS_BUTTON, &dev);
+dev;
+uclass_find_next_device(&dev)) {
+   struct button_uc_plat *plat = dev_get_uclass_platdata(dev);
+
+   if (!plat->label)
+   continue;
+   printf("%-15s ", plat->label);
+   if (device_active(dev)) {
+   ret = show_button_state(dev);
+   if (ret < 0)
+   printf("Error %d\n", ret);
+   } else {
+   printf("\n");
+   }
+   }
+
+   return 0;
+}
+
+int do_button(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
+{
+   const char *button_label;
+   struct udevice *dev;
+   int ret;
+
+   /* Validate arguments */
+   if (argc < 2)
+   return CMD_RET_USAGE;
+   button_label = argv[1];
+   if (strncmp(button_label, "list", 4) == 0)
+   return list_buttons();
+
+   ret = button_get_by_label(button_label, &dev);
+   if (ret) {
+   printf("Button '%s' not found (err=%d)\n", button_label, ret);
+   return CMD_RET_FAILURE;
+   }
+
+   ret = show_button_state(dev);
+
+   return 0;
+}
+
+U_BOOT_CMD(
+   button, 4, 1, do_button,
+   "manage buttons",
+   " \tGet button state\n"
+   "button list\t\tShow a list of buttons"
+);
-- 
2.7.4



[PATCH v2 8/8] test: dm: add a test for class button

2020-07-17 Thread Philippe Reynes
Add a test to confirm that we can read button state
using the button-gpio driver.

Signed-off-by: Philippe Reynes 
---
Changelog:
v2:
- new commit in the serie

 test/dm/Makefile |  1 +
 test/dm/button.c | 74 
 2 files changed, 75 insertions(+)
 create mode 100644 test/dm/button.c

diff --git a/test/dm/Makefile b/test/dm/Makefile
index 6c18fd0..092a70e 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_ACPIGEN) += acpi.o
 obj-$(CONFIG_SOUND) += audio.o
 obj-$(CONFIG_BLK) += blk.o
 obj-$(CONFIG_BOARD) += board.o
+obj-$(CONFIG_BUTTON) += button.o
 obj-$(CONFIG_DM_BOOTCOUNT) += bootcount.o
 obj-$(CONFIG_CLK) += clk.o clk_ccf.o
 obj-$(CONFIG_DEVRES) += devres.o
diff --git a/test/dm/button.c b/test/dm/button.c
new file mode 100644
index 000..890f470
--- /dev/null
+++ b/test/dm/button.c
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 Philippe Reynes 
+ *
+ * Based on led.c
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* Base test of the button uclass */
+static int dm_test_button_base(struct unit_test_state *uts)
+{
+   struct udevice *dev;
+
+   /* Get the top-level device */
+   ut_assertok(uclass_get_device(UCLASS_BUTTON, 0, &dev));
+   ut_assertok(uclass_get_device(UCLASS_BUTTON, 1, &dev));
+   ut_assertok(uclass_get_device(UCLASS_BUTTON, 2, &dev));
+   ut_asserteq(-ENODEV, uclass_get_device(UCLASS_BUTTON, 3, &dev));
+
+   return 0;
+}
+DM_TEST(dm_test_button_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test of the button uclass using the button_gpio driver */
+static int dm_test_button_gpio(struct unit_test_state *uts)
+{
+   const int offset = 3;
+   struct udevice *dev, *gpio;
+
+   /*
+* Check that we can manipulate an BUTTON. BUTTON 1 is connected to GPIO
+* bank gpio_a, offset 3.
+*/
+   ut_assertok(uclass_get_device(UCLASS_BUTTON, 1, &dev));
+   ut_assertok(uclass_get_device(UCLASS_GPIO, 1, &gpio));
+
+   ut_asserteq(0, sandbox_gpio_set_value(gpio, offset, 0));
+   ut_asserteq(0, sandbox_gpio_get_value(gpio, offset));
+   ut_asserteq(BUTTON_OFF, button_get_state(dev));
+
+   ut_asserteq(0, sandbox_gpio_set_value(gpio, offset, 1));
+   ut_asserteq(1, sandbox_gpio_get_value(gpio, offset));
+   ut_asserteq(BUTTON_ON, button_get_state(dev));
+
+   return 0;
+}
+DM_TEST(dm_test_button_gpio, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test obtaining an BUTTON by label */
+static int dm_test_button_label(struct unit_test_state *uts)
+{
+   struct udevice *dev, *cmp;
+
+   ut_assertok(button_get_by_label("summer", &dev));
+   ut_asserteq(1, device_active(dev));
+   ut_assertok(uclass_get_device(UCLASS_BUTTON, 1, &cmp));
+   ut_asserteq_ptr(dev, cmp);
+
+   ut_assertok(button_get_by_label("christmas", &dev));
+   ut_asserteq(1, device_active(dev));
+   ut_assertok(uclass_get_device(UCLASS_BUTTON, 2, &cmp));
+   ut_asserteq_ptr(dev, cmp);
+
+   ut_asserteq(-ENODEV, button_get_by_label("spring", &dev));
+
+   return 0;
+}
+DM_TEST(dm_test_button_label, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
-- 
2.7.4



[PATCH v2 4/8] sandbox: dtsi: add buttons

2020-07-17 Thread Philippe Reynes
Adds two buttons on sandbox so button framework may be tested.

Reviewed-by: Simon Glass 
Signed-off-by: Philippe Reynes 
---
Changelog:
v2:
- no change

 arch/sandbox/dts/sandbox.dtsi | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/arch/sandbox/dts/sandbox.dtsi b/arch/sandbox/dts/sandbox.dtsi
index e1f68cd..bd87dac 100644
--- a/arch/sandbox/dts/sandbox.dtsi
+++ b/arch/sandbox/dts/sandbox.dtsi
@@ -15,6 +15,20 @@
#sound-dai-cells = <1>;
};
 
+   buttons {
+   compatible = "button-gpio";
+
+   summer {
+   gpios = <&gpio_a 3 0>;
+   label = "summer";
+   };
+
+   christmas {
+   gpios = <&gpio_a 4 0>;
+   label = "christmas";
+   };
+   };
+
gpio_a: gpios@0 {
u-boot,dm-pre-reloc;
gpio-controller;
-- 
2.7.4



[PATCH v2 7/8] test/py: add tests for the button commands

2020-07-17 Thread Philippe Reynes
Adds tests for the button commands.

Reviewed-by: Simon Glass 
Signed-off-by: Philippe Reynes 
---
Changelog:
v2:
- no change (button uclass test is added in another commit

 arch/sandbox/dts/test.dts| 14 ++
 test/py/tests/test_button.py | 19 +++
 2 files changed, 33 insertions(+)
 create mode 100644 test/py/tests/test_button.py

diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 5ce5e28..101d729 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -51,6 +51,20 @@
#sound-dai-cells = <1>;
};
 
+   buttons {
+   compatible = "button-gpio";
+
+   summer {
+   gpios = <&gpio_a 3 0>;
+   label = "summer";
+   };
+
+   christmas {
+   gpios = <&gpio_a 4 0>;
+   label = "christmas";
+   };
+   };
+
cros_ec: cros-ec {
reg = <0 0>;
compatible = "google,cros-ec-sandbox";
diff --git a/test/py/tests/test_button.py b/test/py/tests/test_button.py
new file mode 100644
index 000..98067a9
--- /dev/null
+++ b/test/py/tests/test_button.py
@@ -0,0 +1,19 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+import pytest
+
+@pytest.mark.boardspec('sandbox')
+@pytest.mark.buildconfigspec('cmd_button')
+def test_button_exit_statuses(u_boot_console):
+"""Test that non-input button commands correctly return the command
+success/failure status."""
+
+expected_response = 'rc:0'
+response = u_boot_console.run_command('button list; echo rc:$?')
+assert(expected_response in response)
+response = u_boot_console.run_command('button summer; echo rc:$?')
+assert(expected_response in response)
+
+expected_response = 'rc:1'
+response = u_boot_console.run_command('button nonexistent-button; echo 
rc:$?')
+assert(expected_response in response)
-- 
2.7.4



[PATCH v2 2/8] dm: button: add a driver for button driven by gpio

2020-07-17 Thread Philippe Reynes
Add a simple driver which allows use of buttons attached to GPIOs.

Reviewed-by: Simon Glass 
Signed-off-by: Philippe Reynes 
---
Changelog:
v2:
- remove useless default in Kconfig
- re-order include
- fix condition in button_gpio_remove

 drivers/button/Kconfig   |   9 
 drivers/button/Makefile  |   1 +
 drivers/button/button-gpio.c | 111 +++
 3 files changed, 121 insertions(+)
 create mode 100644 drivers/button/button-gpio.c

diff --git a/drivers/button/Kconfig b/drivers/button/Kconfig
index 8301858..6b3ec7e 100644
--- a/drivers/button/Kconfig
+++ b/drivers/button/Kconfig
@@ -9,4 +9,13 @@ config BUTTON
  can provide access to board-specific buttons. Use of the device tree
  for configuration is encouraged.
 
+config BUTTON_GPIO
+   bool "Button gpio"
+   depends on BUTTON
+   help
+ Enable support for buttons which are connected to GPIO lines. These
+ GPIOs may be on the SoC or some other device which provides GPIOs.
+ The GPIO driver must used driver model. Buttons are configured using
+ the device tree.
+
 endmenu
diff --git a/drivers/button/Makefile b/drivers/button/Makefile
index 0b4c128..fcc10eb 100644
--- a/drivers/button/Makefile
+++ b/drivers/button/Makefile
@@ -3,3 +3,4 @@
 # Copyright (C) 2020 Philippe Reynes 
 
 obj-$(CONFIG_BUTTON) += button-uclass.o
+obj-$(CONFIG_BUTTON_GPIO) += button-gpio.o
diff --git a/drivers/button/button-gpio.c b/drivers/button/button-gpio.c
new file mode 100644
index 000..4f71fce
--- /dev/null
+++ b/drivers/button/button-gpio.c
@@ -0,0 +1,111 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 Philippe Reynes 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct button_gpio_priv {
+   struct gpio_desc gpio;
+};
+
+static enum button_state_t button_gpio_get_state(struct udevice *dev)
+{
+   struct button_gpio_priv *priv = dev_get_priv(dev);
+   int ret;
+
+   if (!dm_gpio_is_valid(&priv->gpio))
+   return -EREMOTEIO;
+   ret = dm_gpio_get_value(&priv->gpio);
+   if (ret < 0)
+   return ret;
+
+   return ret ? BUTTON_ON : BUTTON_OFF;
+}
+
+static int button_gpio_probe(struct udevice *dev)
+{
+   struct button_uc_plat *uc_plat = dev_get_uclass_platdata(dev);
+   struct button_gpio_priv *priv = dev_get_priv(dev);
+   int ret;
+
+   /* Ignore the top-level button node */
+   if (!uc_plat->label)
+   return 0;
+
+   ret = gpio_request_by_name(dev, "gpios", 0, &priv->gpio, GPIOD_IS_IN);
+   if (ret)
+   return ret;
+
+   return 0;
+}
+
+static int button_gpio_remove(struct udevice *dev)
+{
+   /*
+* The GPIO driver may have already been removed. We will need to
+* address this more generally.
+*/
+   if (!IS_ENABLED(CONFIG_SANDBOX)) {
+   struct button_gpio_priv *priv = dev_get_priv(dev);
+
+   if (dm_gpio_is_valid(&priv->gpio))
+   dm_gpio_free(dev, &priv->gpio);
+   }
+
+   return 0;
+}
+
+static int button_gpio_bind(struct udevice *parent)
+{
+   struct udevice *dev;
+   ofnode node;
+   int ret;
+
+   dev_for_each_subnode(node, parent) {
+   struct button_uc_plat *uc_plat;
+   const char *label;
+
+   label = ofnode_read_string(node, "label");
+   if (!label) {
+   debug("%s: node %s has no label\n", __func__,
+ ofnode_get_name(node));
+   return -EINVAL;
+   }
+   ret = device_bind_driver_to_node(parent, "button_gpio",
+ofnode_get_name(node),
+node, &dev);
+   if (ret)
+   return ret;
+   uc_plat = dev_get_uclass_platdata(dev);
+   uc_plat->label = label;
+   }
+
+   return 0;
+}
+
+static const struct button_ops button_gpio_ops = {
+   .get_state  = button_gpio_get_state,
+};
+
+static const struct udevice_id button_gpio_ids[] = {
+   { .compatible = "button-gpio" },
+   { }
+};
+
+U_BOOT_DRIVER(button_gpio) = {
+   .name   = "button_gpio",
+   .id = UCLASS_BUTTON,
+   .of_match   = button_gpio_ids,
+   .ops= &button_gpio_ops,
+   .priv_auto_alloc_size = sizeof(struct button_gpio_priv),
+   .bind   = button_gpio_bind,
+   .probe  = button_gpio_probe,
+   .remove = button_gpio_remove,
+};
-- 
2.7.4



[PATCH v2 6/8] sandbox: enable button

2020-07-17 Thread Philippe Reynes
Enable the support of button (driver and command) on sandbox.

Reviewed-by: Simon Glass 
Signed-off-by: Philippe Reynes 
---
Changelog:
v2:
- no change

 configs/sandbox_defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 5b75693..67801ed 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -102,6 +102,8 @@ CONFIG_AXI_SANDBOX=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_DM_BOOTCOUNT=y
 CONFIG_DM_BOOTCOUNT_RTC=y
+CONFIG_BUTTON=y
+CONFIG_BUTTON_GPIO=y
 CONFIG_CLK=y
 CONFIG_CLK_COMPOSITE_CCF=y
 CONFIG_SANDBOX_CLK_CCF=y
-- 
2.7.4



[PATCH v2 1/8] dm: button: add an uclass for button

2020-07-17 Thread Philippe Reynes
Add a new uclass for button that implements two functions:
- button_get_by_label
- button_get_status

Reviewed-by: Simon Glass 
Signed-off-by: Philippe Reynes 
---

Changelog:
v2:
- re-order include
- use uclass_id_foreach_dev
- add comments to enum button_state_t

 drivers/Kconfig|  2 ++
 drivers/Makefile   |  1 +
 drivers/button/Kconfig | 12 +
 drivers/button/Makefile|  5 
 drivers/button/button-uclass.c | 43 ++
 include/button.h   | 59 ++
 include/dm/uclass-id.h |  1 +
 7 files changed, 123 insertions(+)
 create mode 100644 drivers/button/Kconfig
 create mode 100644 drivers/button/Makefile
 create mode 100644 drivers/button/button-uclass.c
 create mode 100644 include/button.h

diff --git a/drivers/Kconfig b/drivers/Kconfig
index e34a227..3cb05aa 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -14,6 +14,8 @@ source "drivers/block/Kconfig"
 
 source "drivers/bootcount/Kconfig"
 
+source "drivers/button/Kconfig"
+
 source "drivers/cache/Kconfig"
 
 source "drivers/clk/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 94e8c5d..727a713 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0+
 
+obj-$(CONFIG_$(SPL_TPL_)BUTTON) += button/
 obj-$(CONFIG_$(SPL_TPL_)CACHE) += cache/
 obj-$(CONFIG_$(SPL_TPL_)CLK) += clk/
 obj-$(CONFIG_$(SPL_TPL_)DM) += core/
diff --git a/drivers/button/Kconfig b/drivers/button/Kconfig
new file mode 100644
index 000..8301858
--- /dev/null
+++ b/drivers/button/Kconfig
@@ -0,0 +1,12 @@
+menu "Button Support"
+
+config BUTTON
+   bool "Enable button support"
+   depends on DM
+   help
+ Many boards have buttons which can be used to change behaviour 
(reset, ...).
+ U-Boot provides a uclass API to implement this feature. Button drivers
+ can provide access to board-specific buttons. Use of the device tree
+ for configuration is encouraged.
+
+endmenu
diff --git a/drivers/button/Makefile b/drivers/button/Makefile
new file mode 100644
index 000..0b4c128
--- /dev/null
+++ b/drivers/button/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2020 Philippe Reynes 
+
+obj-$(CONFIG_BUTTON) += button-uclass.o
diff --git a/drivers/button/button-uclass.c b/drivers/button/button-uclass.c
new file mode 100644
index 000..1c742c2
--- /dev/null
+++ b/drivers/button/button-uclass.c
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 Philippe Reynes 
+ *
+ * Based on led-uclass.c
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+int button_get_by_label(const char *label, struct udevice **devp)
+{
+   struct udevice *dev;
+   struct uclass *uc;
+
+   uclass_id_foreach_dev(UCLASS_BUTTON, dev, uc) {
+   struct button_uc_plat *uc_plat = dev_get_uclass_platdata(dev);
+
+   /* Ignore the top-level button node */
+   if (uc_plat->label && !strcmp(label, uc_plat->label))
+   return uclass_get_device_tail(dev, 0, devp);
+   }
+
+   return -ENODEV;
+}
+
+enum button_state_t button_get_state(struct udevice *dev)
+{
+   struct button_ops *ops = button_get_ops(dev);
+
+   if (!ops->get_state)
+   return -ENOSYS;
+
+   return ops->get_state(dev);
+}
+
+UCLASS_DRIVER(button) = {
+   .id = UCLASS_BUTTON,
+   .name   = "button",
+   .per_device_platdata_auto_alloc_size = sizeof(struct button_uc_plat),
+};
diff --git a/include/button.h b/include/button.h
new file mode 100644
index 000..688b63b
--- /dev/null
+++ b/include/button.h
@@ -0,0 +1,59 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2020 Philippe Reynes 
+ */
+
+#ifndef __BUTTON_H
+#define __BUTTON_H
+
+/**
+ * struct button_uc_plat - Platform data the uclass stores about each device
+ *
+ * @label: Button label
+ */
+struct button_uc_plat {
+   const char *label;
+};
+
+/**
+ * enum button_state_t - State used for button
+ * - BUTTON_OFF - Button is not pressed
+ * - BUTTON_ON - Button is pressed
+ * - BUTTON_COUNT - Number of button state
+ */
+enum button_state_t {
+   BUTTON_OFF = 0,
+   BUTTON_ON = 1,
+   BUTTON_COUNT,
+};
+
+struct button_ops {
+   /**
+* get_state() - get the state of a button
+*
+* @dev:button device to change
+* @return button state button_state_t, or -ve on error
+*/
+   enum button_state_t (*get_state)(struct udevice *dev);
+};
+
+#define button_get_ops(dev)((struct button_ops *)(dev)->driver->ops)
+
+/**
+ * button_get_by_label() - Find a button device by label
+ *
+ * @label: button label to look up
+ * @devp:  Returns the associated device, if found
+ * @return 0 

[PATCH v2 5/8] sandbox64: enable button

2020-07-17 Thread Philippe Reynes
Enable the support of button (driver and command) on sandbox64.

Reviewed-by: Simon Glass 
Signed-off-by: Philippe Reynes 
---
Changelog:
v2:
- no change

 configs/sandbox64_defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig
index a3f049e..89ba504 100644
--- a/configs/sandbox64_defconfig
+++ b/configs/sandbox64_defconfig
@@ -90,6 +90,8 @@ CONFIG_ADC=y
 CONFIG_ADC_SANDBOX=y
 CONFIG_AXI=y
 CONFIG_AXI_SANDBOX=y
+CONFIG_BUTTON=y
+CONFIG_BUTTON_GPIO=y
 CONFIG_CLK=y
 CONFIG_CPU=y
 CONFIG_DM_DEMO=y
-- 
2.7.4



[PATCH 5/7] sandbox64: enable button

2020-07-13 Thread Philippe Reynes
Enable the support of button (driver and command) on sandbox64.

Signed-off-by: Philippe Reynes 
---
 configs/sandbox64_defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig
index a3f049e..89ba504 100644
--- a/configs/sandbox64_defconfig
+++ b/configs/sandbox64_defconfig
@@ -90,6 +90,8 @@ CONFIG_ADC=y
 CONFIG_ADC_SANDBOX=y
 CONFIG_AXI=y
 CONFIG_AXI_SANDBOX=y
+CONFIG_BUTTON=y
+CONFIG_BUTTON_GPIO=y
 CONFIG_CLK=y
 CONFIG_CPU=y
 CONFIG_DM_DEMO=y
-- 
2.7.4



[PATCH 7/7] test/py: add tests for the button commands

2020-07-13 Thread Philippe Reynes
Adds tests for the button commands.

Signed-off-by: Philippe Reynes 
---
 arch/sandbox/dts/test.dts| 14 ++
 test/py/tests/test_button.py | 19 +++
 2 files changed, 33 insertions(+)
 create mode 100644 test/py/tests/test_button.py

diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 5ce5e28..101d729 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -51,6 +51,20 @@
#sound-dai-cells = <1>;
};
 
+   buttons {
+   compatible = "button-gpio";
+
+   summer {
+   gpios = <&gpio_a 3 0>;
+   label = "summer";
+   };
+
+   christmas {
+   gpios = <&gpio_a 4 0>;
+   label = "christmas";
+   };
+   };
+
cros_ec: cros-ec {
reg = <0 0>;
compatible = "google,cros-ec-sandbox";
diff --git a/test/py/tests/test_button.py b/test/py/tests/test_button.py
new file mode 100644
index 000..98067a9
--- /dev/null
+++ b/test/py/tests/test_button.py
@@ -0,0 +1,19 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+import pytest
+
+@pytest.mark.boardspec('sandbox')
+@pytest.mark.buildconfigspec('cmd_button')
+def test_button_exit_statuses(u_boot_console):
+"""Test that non-input button commands correctly return the command
+success/failure status."""
+
+expected_response = 'rc:0'
+response = u_boot_console.run_command('button list; echo rc:$?')
+assert(expected_response in response)
+response = u_boot_console.run_command('button summer; echo rc:$?')
+assert(expected_response in response)
+
+expected_response = 'rc:1'
+response = u_boot_console.run_command('button nonexistent-button; echo 
rc:$?')
+assert(expected_response in response)
-- 
2.7.4



[PATCH 4/7] sandbox: dtsi: add buttons

2020-07-13 Thread Philippe Reynes
Adds two buttons on sandbox so button framework may be tested.

Signed-off-by: Philippe Reynes 
---
 arch/sandbox/dts/sandbox.dtsi | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/arch/sandbox/dts/sandbox.dtsi b/arch/sandbox/dts/sandbox.dtsi
index e1f68cd..bd87dac 100644
--- a/arch/sandbox/dts/sandbox.dtsi
+++ b/arch/sandbox/dts/sandbox.dtsi
@@ -15,6 +15,20 @@
#sound-dai-cells = <1>;
};
 
+   buttons {
+   compatible = "button-gpio";
+
+   summer {
+   gpios = <&gpio_a 3 0>;
+   label = "summer";
+   };
+
+   christmas {
+   gpios = <&gpio_a 4 0>;
+   label = "christmas";
+   };
+   };
+
gpio_a: gpios@0 {
u-boot,dm-pre-reloc;
gpio-controller;
-- 
2.7.4



[PATCH 1/7] dm: button: add an uclass for button

2020-07-13 Thread Philippe Reynes
Add a new uclass for button that implements two functions:
- button_get_by_label
- button_get_status

Signed-off-by: Philippe Reynes 
---
 drivers/Kconfig|  2 ++
 drivers/Makefile   |  1 +
 drivers/button/Kconfig | 12 ++
 drivers/button/Makefile|  5 
 drivers/button/button-uclass.c | 47 +
 include/button.h   | 53 ++
 include/dm/uclass-id.h |  1 +
 7 files changed, 121 insertions(+)
 create mode 100644 drivers/button/Kconfig
 create mode 100644 drivers/button/Makefile
 create mode 100644 drivers/button/button-uclass.c
 create mode 100644 include/button.h

diff --git a/drivers/Kconfig b/drivers/Kconfig
index e34a227..3cb05aa 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -14,6 +14,8 @@ source "drivers/block/Kconfig"
 
 source "drivers/bootcount/Kconfig"
 
+source "drivers/button/Kconfig"
+
 source "drivers/cache/Kconfig"
 
 source "drivers/clk/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 94e8c5d..727a713 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0+
 
+obj-$(CONFIG_$(SPL_TPL_)BUTTON) += button/
 obj-$(CONFIG_$(SPL_TPL_)CACHE) += cache/
 obj-$(CONFIG_$(SPL_TPL_)CLK) += clk/
 obj-$(CONFIG_$(SPL_TPL_)DM) += core/
diff --git a/drivers/button/Kconfig b/drivers/button/Kconfig
new file mode 100644
index 000..8301858
--- /dev/null
+++ b/drivers/button/Kconfig
@@ -0,0 +1,12 @@
+menu "Button Support"
+
+config BUTTON
+   bool "Enable button support"
+   depends on DM
+   help
+ Many boards have buttons which can be used to change behaviour 
(reset, ...).
+ U-Boot provides a uclass API to implement this feature. Button drivers
+ can provide access to board-specific buttons. Use of the device tree
+ for configuration is encouraged.
+
+endmenu
diff --git a/drivers/button/Makefile b/drivers/button/Makefile
new file mode 100644
index 000..0b4c128
--- /dev/null
+++ b/drivers/button/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2020 Philippe Reynes 
+
+obj-$(CONFIG_BUTTON) += button-uclass.o
diff --git a/drivers/button/button-uclass.c b/drivers/button/button-uclass.c
new file mode 100644
index 000..d6cda78
--- /dev/null
+++ b/drivers/button/button-uclass.c
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 Philippe Reynes 
+ *
+ * Based on led-uclass.c
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+int button_get_by_label(const char *label, struct udevice **devp)
+{
+   struct udevice *dev;
+   struct uclass *uc;
+   int ret;
+
+   ret = uclass_get(UCLASS_BUTTON, &uc);
+   if (ret)
+   return ret;
+   uclass_foreach_dev(dev, uc) {
+   struct button_uc_plat *uc_plat = dev_get_uclass_platdata(dev);
+
+   /* Ignore the top-level button node */
+   if (uc_plat->label && !strcmp(label, uc_plat->label))
+   return uclass_get_device_tail(dev, 0, devp);
+   }
+
+   return -ENODEV;
+}
+
+enum button_state_t button_get_state(struct udevice *dev)
+{
+   struct button_ops *ops = button_get_ops(dev);
+
+   if (!ops->get_state)
+   return -ENOSYS;
+
+   return ops->get_state(dev);
+}
+
+UCLASS_DRIVER(button) = {
+   .id = UCLASS_BUTTON,
+   .name   = "button",
+   .per_device_platdata_auto_alloc_size = sizeof(struct button_uc_plat),
+};
diff --git a/include/button.h b/include/button.h
new file mode 100644
index 000..333fc23
--- /dev/null
+++ b/include/button.h
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2020 Philippe Reynes 
+ */
+
+#ifndef __BUTTON_H
+#define __BUTTON_H
+
+/**
+ * struct button_uc_plat - Platform data the uclass stores about each device
+ *
+ * @label: Button label
+ */
+struct button_uc_plat {
+   const char *label;
+};
+
+enum button_state_t {
+   BUTTON_OFF = 0,
+   BUTTON_ON = 1,
+   BUTTON_COUNT,
+};
+
+struct button_ops {
+   /**
+* get_state() - get the state of a button
+*
+* @dev:button device to change
+* @return button state button_state_t, or -ve on error
+*/
+   enum button_state_t (*get_state)(struct udevice *dev);
+};
+
+#define button_get_ops(dev)((struct button_ops *)(dev)->driver->ops)
+
+/**
+ * button_get_by_label() - Find a button device by label
+ *
+ * @label: button label to look up
+ * @devp:  Returns the associated device, if found
+ * @return 0 if found, -ENODEV if not found, other -ve on error
+ */
+int button_get_by_label(const char *label, struct udevice **devp);
+
+/**
+ * button_get_state() - get the state of a button
+ *
+ * @dev:   

[PATCH 6/7] sandbox: enable button

2020-07-13 Thread Philippe Reynes
Enable the support of button (driver and command) on sandbox.

Signed-off-by: Philippe Reynes 
---
 configs/sandbox_defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 5b75693..67801ed 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -102,6 +102,8 @@ CONFIG_AXI_SANDBOX=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_DM_BOOTCOUNT=y
 CONFIG_DM_BOOTCOUNT_RTC=y
+CONFIG_BUTTON=y
+CONFIG_BUTTON_GPIO=y
 CONFIG_CLK=y
 CONFIG_CLK_COMPOSITE_CCF=y
 CONFIG_SANDBOX_CLK_CCF=y
-- 
2.7.4



[PATCH 3/7] cmd: button: add a new 'button' command

2020-07-13 Thread Philippe Reynes
Adds a command 'button' that provides the list of buttons
supported by the board, and the state of a button.

Signed-off-by: Philippe Reynes 
---
 cmd/Kconfig  | 11 
 cmd/Makefile |  1 +
 cmd/button.c | 86 
 3 files changed, 98 insertions(+)
 create mode 100644 cmd/button.c

diff --git a/cmd/Kconfig b/cmd/Kconfig
index 192b3b2..750d26a 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -1664,6 +1664,17 @@ config CMD_BLOCK_CACHE
  during development, but also allows the cache to be disabled when
  it might hurt performance (e.g. when using the ums command).
 
+config CMD_BUTTON
+   bool "button"
+   depends on BUTTON
+   default y if BUTTON
+   help
+ Enable the 'button' command which allows to get the status of
+ buttons supported by the board. The buttonss can be listed with
+ 'button list' and state can be known with 'button '.
+ Any button drivers can be controlled with this command, e.g.
+ button_gpio.
+
 config CMD_CACHE
bool "icache or dcache"
help
diff --git a/cmd/Makefile b/cmd/Makefile
index 974ad48..5ded3a6 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_CMD_BOOTSTAGE) += bootstage.o
 obj-$(CONFIG_CMD_BOOTZ) += bootz.o
 obj-$(CONFIG_CMD_BOOTI) += booti.o
 obj-$(CONFIG_CMD_BTRFS) += btrfs.o
+obj-$(CONFIG_CMD_BUTTON) += button.o
 obj-$(CONFIG_CMD_CACHE) += cache.o
 obj-$(CONFIG_CMD_CBFS) += cbfs.o
 obj-$(CONFIG_CMD_CLK) += clk.o
diff --git a/cmd/button.c b/cmd/button.c
new file mode 100644
index 000..84ad165
--- /dev/null
+++ b/cmd/button.c
@@ -0,0 +1,86 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 Philippe Reynes 
+ *
+ * Based on led.c
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static const char *const state_label[] = {
+   [BUTTON_OFF]= "off",
+   [BUTTON_ON] = "on",
+};
+
+static int show_button_state(struct udevice *dev)
+{
+   int ret;
+
+   ret = button_get_state(dev);
+   if (ret >= BUTTON_COUNT)
+   ret = -EINVAL;
+   if (ret >= 0)
+   printf("%s\n", state_label[ret]);
+
+   return ret;
+}
+
+static int list_buttons(void)
+{
+   struct udevice *dev;
+   int ret;
+
+   for (uclass_find_first_device(UCLASS_BUTTON, &dev);
+dev;
+uclass_find_next_device(&dev)) {
+   struct button_uc_plat *plat = dev_get_uclass_platdata(dev);
+
+   if (!plat->label)
+   continue;
+   printf("%-15s ", plat->label);
+   if (device_active(dev)) {
+   ret = show_button_state(dev);
+   if (ret < 0)
+   printf("Error %d\n", ret);
+   } else {
+   printf("\n");
+   }
+   }
+
+   return 0;
+}
+
+int do_button(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
+{
+   const char *button_label;
+   struct udevice *dev;
+   int ret;
+
+   /* Validate arguments */
+   if (argc < 2)
+   return CMD_RET_USAGE;
+   button_label = argv[1];
+   if (strncmp(button_label, "list", 4) == 0)
+   return list_buttons();
+
+   ret = button_get_by_label(button_label, &dev);
+   if (ret) {
+   printf("Button '%s' not found (err=%d)\n", button_label, ret);
+   return CMD_RET_FAILURE;
+   }
+
+   ret = show_button_state(dev);
+
+   return 0;
+}
+
+U_BOOT_CMD(
+   button, 4, 1, do_button,
+   "manage buttons",
+   " \tGet button state\n"
+   "button list\t\tShow a list of buttons"
+);
-- 
2.7.4



[PATCH 2/7] dm: button: add a driver for button driven by gpio

2020-07-13 Thread Philippe Reynes
Add a simple driver which allows use of buttons attached to GPIOs.

Signed-off-by: Philippe Reynes 
---
 drivers/button/Kconfig   |  10 
 drivers/button/Makefile  |   1 +
 drivers/button/button-gpio.c | 111 +++
 3 files changed, 122 insertions(+)
 create mode 100644 drivers/button/button-gpio.c

diff --git a/drivers/button/Kconfig b/drivers/button/Kconfig
index 8301858..7de1a97 100644
--- a/drivers/button/Kconfig
+++ b/drivers/button/Kconfig
@@ -9,4 +9,14 @@ config BUTTON
  can provide access to board-specific buttons. Use of the device tree
  for configuration is encouraged.
 
+config BUTTON_GPIO
+   bool "Button gpio"
+   depends on BUTTON
+   default n
+   help
+ Enable support for buttons which are connected to GPIO lines. These
+ GPIOs may be on the SoC or some other device which provides GPIOs.
+ The GPIO driver must used driver model. Buttons are configured using
+ the device tree.
+
 endmenu
diff --git a/drivers/button/Makefile b/drivers/button/Makefile
index 0b4c128..fcc10eb 100644
--- a/drivers/button/Makefile
+++ b/drivers/button/Makefile
@@ -3,3 +3,4 @@
 # Copyright (C) 2020 Philippe Reynes 
 
 obj-$(CONFIG_BUTTON) += button-uclass.o
+obj-$(CONFIG_BUTTON_GPIO) += button-gpio.o
diff --git a/drivers/button/button-gpio.c b/drivers/button/button-gpio.c
new file mode 100644
index 000..6ad0094
--- /dev/null
+++ b/drivers/button/button-gpio.c
@@ -0,0 +1,111 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 Philippe Reynes 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct button_gpio_priv {
+   struct gpio_desc gpio;
+};
+
+static enum button_state_t button_gpio_get_state(struct udevice *dev)
+{
+   struct button_gpio_priv *priv = dev_get_priv(dev);
+   int ret;
+
+   if (!dm_gpio_is_valid(&priv->gpio))
+   return -EREMOTEIO;
+   ret = dm_gpio_get_value(&priv->gpio);
+   if (ret < 0)
+   return ret;
+
+   return ret ? BUTTON_ON : BUTTON_OFF;
+}
+
+static int button_gpio_probe(struct udevice *dev)
+{
+   struct button_uc_plat *uc_plat = dev_get_uclass_platdata(dev);
+   struct button_gpio_priv *priv = dev_get_priv(dev);
+   int ret;
+
+   /* Ignore the top-level button node */
+   if (!uc_plat->label)
+   return 0;
+
+   ret = gpio_request_by_name(dev, "gpios", 0, &priv->gpio, GPIOD_IS_IN);
+   if (ret)
+   return ret;
+
+   return 0;
+}
+
+static int button_gpio_remove(struct udevice *dev)
+{
+   /*
+* The GPIO driver may have already been removed. We will need to
+* address this more generally.
+*/
+   if (IS_ENABLED(CONFIG_SANDBOX)) {
+   struct button_gpio_priv *priv = dev_get_priv(dev);
+
+   if (dm_gpio_is_valid(&priv->gpio))
+   dm_gpio_free(dev, &priv->gpio);
+   }
+
+   return 0;
+}
+
+static int button_gpio_bind(struct udevice *parent)
+{
+   struct udevice *dev;
+   ofnode node;
+   int ret;
+
+   dev_for_each_subnode(node, parent) {
+   struct button_uc_plat *uc_plat;
+   const char *label;
+
+   label = ofnode_read_string(node, "label");
+   if (!label) {
+   debug("%s: node %s has no label\n", __func__,
+ ofnode_get_name(node));
+   return -EINVAL;
+   }
+   ret = device_bind_driver_to_node(parent, "button_gpio",
+ofnode_get_name(node),
+node, &dev);
+   if (ret)
+   return ret;
+   uc_plat = dev_get_uclass_platdata(dev);
+   uc_plat->label = label;
+   }
+
+   return 0;
+}
+
+static const struct button_ops button_gpio_ops = {
+   .get_state  = button_gpio_get_state,
+};
+
+static const struct udevice_id button_gpio_ids[] = {
+   { .compatible = "button-gpio" },
+   { }
+};
+
+U_BOOT_DRIVER(button_gpio) = {
+   .name   = "button_gpio",
+   .id = UCLASS_BUTTON,
+   .of_match   = button_gpio_ids,
+   .ops= &button_gpio_ops,
+   .priv_auto_alloc_size = sizeof(struct button_gpio_priv),
+   .bind   = button_gpio_bind,
+   .probe  = button_gpio_probe,
+   .remove = button_gpio_remove,
+};
-- 
2.7.4



[PATCH] lib: libfdt: fdt_region: avoid NULL pointer access

2020-07-02 Thread Philippe Reynes
The function fdt_find_regions look in the exclude list for each
property, even if the name is NULL. It could happen if the fit
image is corrupted. On sandbox, it generates a segfault.

To avoid this issue, if the name of a property is NULL, we report
an error and avoid looking in the exclude list.

Signed-off-by: Philippe Reynes 
---
 common/fdt_region.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/common/fdt_region.c b/common/fdt_region.c
index 6676590..ff12c51 100644
--- a/common/fdt_region.c
+++ b/common/fdt_region.c
@@ -65,6 +65,8 @@ int fdt_find_regions(const void *fdt, char * const inc[], int 
inc_count,
stop_at = offset;
prop = fdt_get_property_by_offset(fdt, offset, NULL);
str = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));
+   if (!str)
+   return -FDT_ERR_BADSTRUCTURE;
if (str_in_list(str, exc_prop, exc_prop_count))
include = 0;
break;
-- 
2.7.4



[PATCH v3 1/2] test/py: vboot: add a test to check fit signature on fit with padding

2020-04-29 Thread Philippe Reynes
The pytest vboot does all his tests on fit without padding.
We add the same tests on fit with padding.

Reviewed-by: Simon Glass 
Signed-off-by: Philippe Reynes 
---
 test/py/tests/test_vboot.py | 52 -
 1 file changed, 33 insertions(+), 19 deletions(-)

Changelog:
v3:
- rebase on master
v2:
- no change

diff --git a/test/py/tests/test_vboot.py b/test/py/tests/test_vboot.py
index e67f2b3..6b998cf 100644
--- a/test/py/tests/test_vboot.py
+++ b/test/py/tests/test_vboot.py
@@ -30,11 +30,16 @@ import u_boot_utils as util
 import vboot_forge
 
 TESTDATA = [
-['sha1', '', False],
-['sha1', '-pss', False],
-['sha256', '', False],
-['sha256', '-pss', False],
-['sha256', '-pss', True],
+['sha1', '', None, False],
+['sha1', '', '-E -p 0x1', False],
+['sha1', '-pss', None, False],
+['sha1', '-pss', '-E -p 0x1', False],
+['sha256', '', None, False],
+['sha256', '', '-E -p 0x1', False],
+['sha256', '-pss', None, False],
+['sha256', '-pss', '-E -p 0x1', False],
+['sha256', '-pss', None, True],
+['sha256', '-pss', '-E -p 0x1', True],
 ]
 
 @pytest.mark.boardspec('sandbox')
@@ -43,8 +48,8 @@ TESTDATA = [
 @pytest.mark.requiredtool('fdtget')
 @pytest.mark.requiredtool('fdtput')
 @pytest.mark.requiredtool('openssl')
-@pytest.mark.parametrize("sha_algo,padding,required", TESTDATA)
-def test_vboot(u_boot_console, sha_algo, padding, required):
+@pytest.mark.parametrize("sha_algo,padding,sign_options,required", TESTDATA)
+def test_vboot(u_boot_console, sha_algo, padding, sign_options, required):
 """Test verified boot signing with mkimage and verification with 'bootm'.
 
 This works using sandbox only as it needs to update the device tree used
@@ -104,7 +109,7 @@ def test_vboot(u_boot_console, sha_algo, padding, required):
 util.run_and_log(cons, [mkimage, '-D', dtc_args, '-f',
 '%s%s' % (datadir, its), fit])
 
-def sign_fit(sha_algo):
+def sign_fit(sha_algo, options):
 """Sign the FIT
 
 Signs the FIT and writes the signature into it. It also writes the
@@ -113,10 +118,13 @@ def test_vboot(u_boot_console, sha_algo, padding, 
required):
 Args:
 sha_algo: Either 'sha1' or 'sha256', to select the algorithm to
 use.
+options: Options to provide to mkimage.
 """
+args = [mkimage, '-F', '-k', tmpdir, '-K', dtb, '-r', fit]
+if options:
+args += options.split(' ')
 cons.log.action('%s: Sign images' % sha_algo)
-util.run_and_log(cons, [mkimage, '-F', '-k', tmpdir, '-K', dtb,
-'-r', fit])
+util.run_and_log(cons, args)
 
 def replace_fit_totalsize(size):
 """Replace FIT header's totalsize with something greater.
@@ -154,7 +162,7 @@ def test_vboot(u_boot_console, sha_algo, padding, required):
 util.run_and_log(cons, 'openssl req -batch -new -x509 -key %s%s.key '
  '-out %s%s.crt' % (tmpdir, name, tmpdir, name))
 
-def test_with_algo(sha_algo, padding):
+def test_with_algo(sha_algo, padding, sign_options):
 """Test verified boot with the given hash algorithm.
 
 This is the main part of the test code. The same procedure is followed
@@ -163,6 +171,9 @@ def test_vboot(u_boot_console, sha_algo, padding, required):
 Args:
 sha_algo: Either 'sha1' or 'sha256', to select the algorithm to
 use.
+padding: Either '' or '-pss', to select the padding to use for the
+rsa signature algorithm.
+sign_options: Options to mkimage when signing a fit image.
 """
 # Compile our device tree files for kernel and U-Boot. These are
 # regenerated here since mkimage will modify them (by adding a
@@ -176,7 +187,7 @@ def test_vboot(u_boot_console, sha_algo, padding, required):
 run_bootm(sha_algo, 'unsigned images', 'dev-', True)
 
 # Sign images with our dev keys
-sign_fit(sha_algo)
+sign_fit(sha_algo, sign_options)
 run_bootm(sha_algo, 'signed images', 'dev+', True

[PATCH v3 2/2] rsa: sig: fix config signature check for fit with padding

2020-04-29 Thread Philippe Reynes
The signature check on config node is broken on fit with padding.
To compute the signature for config node, U-Boot compute the
signature on all properties of requested node for this config,
except for the property "data". But, when padding is used for
binary in a fit, there isn't a property "data" but two properties:
"data-offset" and "data-size". So to fix the check of signature,
we also don't use the properties "data-offset" and "data-size"
when checking the signature on config node.

Reviewed-by: Simon Glass 
Signed-off-by: Philippe Reynes 
---
 common/image-fit-sig.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Changelog:
v3:
- rebase on master
v2:
- fix spelling in commit message (thanks Simon)

diff --git a/common/image-fit-sig.c b/common/image-fit-sig.c
index 3e73578..a3a0c61 100644
--- a/common/image-fit-sig.c
+++ b/common/image-fit-sig.c
@@ -249,7 +249,7 @@ static int fit_config_check_sig(const void *fit, int 
noffset,
int required_keynode, int conf_noffset,
char **err_msgp)
 {
-   char * const exc_prop[] = {"data"};
+   char * const exc_prop[] = {"data", "data-size", "data-position"};
const char *prop, *end, *name;
struct image_sign_info info;
const uint32_t *strings;
-- 
2.7.4



[PATCH v3 0/2] test/py: vboot: fix signature check on config node

2020-04-29 Thread Philippe Reynes
The signature check of config node is broken when used on fit with padding.
We didn't see it before because this case is not covered by vboot test.

When check the signature for a config nde, u-boot uses all the properties
of the node referenced in the config node, except the property data. When
padding is used on fit, the property data is replaced by two properties:
data-offset and data-size, and u-boot uses those properties when checking
the signature. To fix this signature check, we simply ignore the properties
data-offset and data_size.

The first commit add some vboot tests that check signature on fit with
padding. The second commit fixes the signature check on config node for
fit with padding.

Philippe Reynes (2):
  test/py: vboot: add a test to check fit signature on fit with padding
  rsa: sig: fix config signature check for fit with padding

Changelog:
v3:
- rebase on master
v2:
- fix spelling in commit message (thanks Simon)

 common/image-fit-sig.c  |  2 +-
 test/py/tests/test_vboot.py | 52 -
 2 files changed, 34 insertions(+), 20 deletions(-)

-- 
2.7.4



[PATCH v2 2/2] rsa: sig: fix config signature check for fit with padding

2020-03-28 Thread Philippe Reynes
The signature check on config node is broken on fit with padding.
To compute the signature for config node, U-Boot compute the
signature on all properties of requested node for this config,
except for the property "data". But, when padding is used for
binary in a fit, there isn't a property "data" but two properties:
"data-offset" and "data-size". So to fix the check of signature,
we also don't use the properties "data-offset" and "data-size"
when checking the signature on config node.

Reviewed-by: Simon Glass 
Signed-off-by: Philippe Reynes 
---
 common/image-sig.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Changelog:
v2:
- fix spelling in commit message (thanks Simon)

diff --git a/common/image-sig.c b/common/image-sig.c
index 639a112..8a0ea28 100644
--- a/common/image-sig.c
+++ b/common/image-sig.c
@@ -362,7 +362,7 @@ int fit_image_verify_required_sigs(const void *fit, int 
image_noffset,
 int fit_config_check_sig(const void *fit, int noffset, int required_keynode,
 char **err_msgp)
 {
-   char * const exc_prop[] = {"data"};
+   char * const exc_prop[] = {"data", "data-size", "data-position"};
const char *prop, *end, *name;
struct image_sign_info info;
const uint32_t *strings;
-- 
2.7.4



[PATCH v2 0/2] test/py: vboot: fix signature check on config node

2020-03-28 Thread Philippe Reynes
The signature check of config node is broken when used on fit with padding.
We didn't see it before because this case is not covered by vboot test.

When check the signature for a config nde, u-boot uses all the properties
of the node referenced in the config node, except the property data. When
padding is used on fit, the property data is replaced by two properties:
data-offset and data-size, and u-boot uses those properties when checking
the signature. To fix this signature check, we simply ignore the properties
data-offset and data_size.

The first commit add some vboot tests that check signature on fit with
padding. The second commit fixes the signature check on config node for
fit with padding.

Philippe Reynes (2):
  test/py: vboot: add a test to check fit signature on fit with padding
  rsa: sig: fix config signature check for fit with padding

Changelog:
v2:
- fix spelling in commit message (thanks Simon)

 common/image-sig.c  |  2 +-
 test/py/tests/test_vboot.py | 42 --
 2 files changed, 29 insertions(+), 15 deletions(-)

-- 
2.7.4



[PATCH v2 1/2] test/py: vboot: add a test to check fit signature on fit with padding

2020-03-28 Thread Philippe Reynes
The pytest vboot does all his tests on fit without padding.
We add the same tests on fit with padding.

Reviewed-by: Simon Glass 
Signed-off-by: Philippe Reynes 
---
 test/py/tests/test_vboot.py | 42 --
 1 file changed, 28 insertions(+), 14 deletions(-)

Changelog:
v2:
- no change

diff --git a/test/py/tests/test_vboot.py b/test/py/tests/test_vboot.py
index 9c41ee5..32299be 100644
--- a/test/py/tests/test_vboot.py
+++ b/test/py/tests/test_vboot.py
@@ -94,7 +94,7 @@ def test_vboot(u_boot_console):
 util.run_and_log(cons, [mkimage, '-D', dtc_args, '-f',
 '%s%s' % (datadir, its), fit])
 
-def sign_fit(sha_algo):
+def sign_fit(sha_algo, options):
 """Sign the FIT
 
 Signs the FIT and writes the signature into it. It also writes the
@@ -103,10 +103,13 @@ def test_vboot(u_boot_console):
 Args:
 sha_algo: Either 'sha1' or 'sha256', to select the algorithm to
 use.
+options: Options to provide to mkimage.
 """
+args = [mkimage, '-F', '-k', tmpdir, '-K', dtb, '-r', fit]
+if options:
+args += options.split(' ')
 cons.log.action('%s: Sign images' % sha_algo)
-util.run_and_log(cons, [mkimage, '-F', '-k', tmpdir, '-K', dtb,
-'-r', fit])
+util.run_and_log(cons, args)
 
 def sign_fit_norequire(sha_algo):
 """Sign the FIT
@@ -142,7 +145,7 @@ def test_vboot(u_boot_console):
 handle.write(struct.pack(">I", size))
 return struct.unpack(">I", total_size)[0]
 
-def test_with_algo(sha_algo, padding):
+def test_with_algo(sha_algo, padding, sign_options):
 """Test verified boot with the given hash algorithm.
 
 This is the main part of the test code. The same procedure is followed
@@ -151,6 +154,9 @@ def test_vboot(u_boot_console):
 Args:
 sha_algo: Either 'sha1' or 'sha256', to select the algorithm to
 use.
+padding: Either '' or '-pss', to select the padding to use for the
+rsa signature algorithm.
+sign_options: Options to mkimage when signing a fit image.
 """
 # Compile our device tree files for kernel and U-Boot. These are
 # regenerated here since mkimage will modify them (by adding a
@@ -164,7 +170,7 @@ def test_vboot(u_boot_console):
 run_bootm(sha_algo, 'unsigned images', 'dev-', True)
 
 # Sign images with our dev keys
-sign_fit(sha_algo)
+sign_fit(sha_algo, sign_options)
 run_bootm(sha_algo, 'signed images', 'dev+', True)
 
 # Create a fresh .dtb without the public keys
@@ -175,7 +181,7 @@ def test_vboot(u_boot_console):
 run_bootm(sha_algo, 'unsigned config', '%s+ OK' % sha_algo, True)
 
 # Sign images with our dev keys
-sign_fit(sha_algo)
+sign_fit(sha_algo, sign_options)
 run_bootm(sha_algo, 'signed config', 'dev+', True)
 
 cons.log.action('%s: Check signed config on the host' % sha_algo)
@@ -211,7 +217,7 @@ def test_vboot(u_boot_console):
 util.run_and_log_expect_exception(cons, [fit_check_sign, '-f', fit,
 '-k', dtb], 1, 'Failed to verify required signature')
 
-def test_required_key(sha_algo, padding):
+def test_required_key(sha_algo, padding, sign_options):
 """Test verified boot with the given hash algorithm.
 
 This function test if u-boot reject an image when a required
@@ -220,6 +226,9 @@ def test_vboot(u_boot_console):
 Args:
 sha_algo: Either 'sha1' or 'sha256', to select the algorithm to
 use.
+padding: Either '' or '-pss', to select the padding to use for the
+rsa signature algorithm.
+sign_options: Options to mkimage when signing a fit image.
 """
 # Compile our device tree files for kernel and U-Boot. These are
 # regenerated here since mkimage will modify them (by adding a
@@ -234,9 +243,9 @@ def test_vboot(u_boot_console):
 # This FIT should not be accepted by u-boot because the key prod is 
required
 cons.log.action('%s: Test FIT with configs images' % sha_algo)
 make_fit('sign-configs-%s%s-prod.its' % (sha_algo , padding))
-sign_fit(sha_algo)
+sign_fit(sha_algo, sign_options)
 make_fit('sign-conf

[PATCH 2/2] rsa: sig: fix config signature check for fit with padding

2020-03-27 Thread Philippe Reynes
The signature check on config node is broken on fit with padding.
To compute the signature for config node, u-boot compute the
signature on all properties of requested node for this config,
except for the property "data". But, when padding is used for
binary in a fit, there isn't a property "data" but two properties:
"data-offset" and "data-size". So to fix the check of signature,
we also dont use the properties "data-offset" and "data-size"
when checking the signature on config node.

Signed-off-by: Philippe Reynes 
---
 common/image-sig.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/common/image-sig.c b/common/image-sig.c
index 639a112..8a0ea28 100644
--- a/common/image-sig.c
+++ b/common/image-sig.c
@@ -362,7 +362,7 @@ int fit_image_verify_required_sigs(const void *fit, int 
image_noffset,
 int fit_config_check_sig(const void *fit, int noffset, int required_keynode,
 char **err_msgp)
 {
-   char * const exc_prop[] = {"data"};
+   char * const exc_prop[] = {"data", "data-size", "data-position"};
const char *prop, *end, *name;
struct image_sign_info info;
const uint32_t *strings;
-- 
2.7.4



[PATCH 1/2] test/py: vboot: add a test to check fit signature on fit with padding

2020-03-27 Thread Philippe Reynes
The pytest vboot does all his tests on fit without padding.
We add the same tests on fit with padding.

Signed-off-by: Philippe Reynes 
---
 test/py/tests/test_vboot.py | 42 --
 1 file changed, 28 insertions(+), 14 deletions(-)

diff --git a/test/py/tests/test_vboot.py b/test/py/tests/test_vboot.py
index 9c41ee5..32299be 100644
--- a/test/py/tests/test_vboot.py
+++ b/test/py/tests/test_vboot.py
@@ -94,7 +94,7 @@ def test_vboot(u_boot_console):
 util.run_and_log(cons, [mkimage, '-D', dtc_args, '-f',
 '%s%s' % (datadir, its), fit])
 
-def sign_fit(sha_algo):
+def sign_fit(sha_algo, options):
 """Sign the FIT
 
 Signs the FIT and writes the signature into it. It also writes the
@@ -103,10 +103,13 @@ def test_vboot(u_boot_console):
 Args:
 sha_algo: Either 'sha1' or 'sha256', to select the algorithm to
 use.
+options: Options to provide to mkimage.
 """
+args = [mkimage, '-F', '-k', tmpdir, '-K', dtb, '-r', fit]
+if options:
+args += options.split(' ')
 cons.log.action('%s: Sign images' % sha_algo)
-util.run_and_log(cons, [mkimage, '-F', '-k', tmpdir, '-K', dtb,
-'-r', fit])
+util.run_and_log(cons, args)
 
 def sign_fit_norequire(sha_algo):
 """Sign the FIT
@@ -142,7 +145,7 @@ def test_vboot(u_boot_console):
 handle.write(struct.pack(">I", size))
 return struct.unpack(">I", total_size)[0]
 
-def test_with_algo(sha_algo, padding):
+def test_with_algo(sha_algo, padding, sign_options):
 """Test verified boot with the given hash algorithm.
 
 This is the main part of the test code. The same procedure is followed
@@ -151,6 +154,9 @@ def test_vboot(u_boot_console):
 Args:
 sha_algo: Either 'sha1' or 'sha256', to select the algorithm to
 use.
+padding: Either '' or '-pss', to select the padding to use for the
+rsa signature algorithm.
+sign_options: Options to mkimage when signing a fit image.
 """
 # Compile our device tree files for kernel and U-Boot. These are
 # regenerated here since mkimage will modify them (by adding a
@@ -164,7 +170,7 @@ def test_vboot(u_boot_console):
 run_bootm(sha_algo, 'unsigned images', 'dev-', True)
 
 # Sign images with our dev keys
-sign_fit(sha_algo)
+sign_fit(sha_algo, sign_options)
 run_bootm(sha_algo, 'signed images', 'dev+', True)
 
 # Create a fresh .dtb without the public keys
@@ -175,7 +181,7 @@ def test_vboot(u_boot_console):
 run_bootm(sha_algo, 'unsigned config', '%s+ OK' % sha_algo, True)
 
 # Sign images with our dev keys
-sign_fit(sha_algo)
+sign_fit(sha_algo, sign_options)
 run_bootm(sha_algo, 'signed config', 'dev+', True)
 
 cons.log.action('%s: Check signed config on the host' % sha_algo)
@@ -211,7 +217,7 @@ def test_vboot(u_boot_console):
 util.run_and_log_expect_exception(cons, [fit_check_sign, '-f', fit,
 '-k', dtb], 1, 'Failed to verify required signature')
 
-def test_required_key(sha_algo, padding):
+def test_required_key(sha_algo, padding, sign_options):
 """Test verified boot with the given hash algorithm.
 
 This function test if u-boot reject an image when a required
@@ -220,6 +226,9 @@ def test_vboot(u_boot_console):
 Args:
 sha_algo: Either 'sha1' or 'sha256', to select the algorithm to
 use.
+padding: Either '' or '-pss', to select the padding to use for the
+rsa signature algorithm.
+sign_options: Options to mkimage when signing a fit image.
 """
 # Compile our device tree files for kernel and U-Boot. These are
 # regenerated here since mkimage will modify them (by adding a
@@ -234,9 +243,9 @@ def test_vboot(u_boot_console):
 # This FIT should not be accepted by u-boot because the key prod is 
required
 cons.log.action('%s: Test FIT with configs images' % sha_algo)
 make_fit('sign-configs-%s%s-prod.its' % (sha_algo , padding))
-sign_fit(sha_algo)
+sign_fit(sha_algo, sign_options)
 make_fit('sign-configs-%s%s.its' % (sha_algo , padding))

[PATCH 0/2] test/py: vboot: fix signature check on config node

2020-03-27 Thread Philippe Reynes
The signature check of config node is broken when used on fit with padding.
We didn't see it before because this case is not covered by vboot test.

When check the signature for a config nde, u-boot uses all the properties
of the node referenced in the config node, except the property data. When
padding is used on fit, the property data is replaced by two properties:
data-offset and data-size, and u-boot uses those properties when checking
the signature. To fix this signature check, we simply ignore the properties
data-offset and data_size.

The first commit add some vboot tests that check signature on fit with
padding. The second commit fixes the signature check on config node for
fit with padding.

Philippe Reynes (2):
  test/py: vboot: add a test to check fit signature on fit with padding
  rsa: sig: fix config signature check for fit with padding

 common/image-sig.c  |  2 +-
 test/py/tests/test_vboot.py | 42 --
 2 files changed, 29 insertions(+), 15 deletions(-)

-- 
2.7.4



Re: [PATCH v2] cmd: ubi: add a command to rename volume

2020-03-23 Thread Philippe REYNES
Hi Rasmus,

> On 23/03/2020 18.16, Philippe REYNES wrote:
> 
>>>> +#ifdef CONFIG_CMD_UBI_RENAME
>>> 
>>> Can you use IS_ENABLED(CONFIG_...) and drop the #ifdef way above?
>> 
>> I've sent a v3 where I use IS_ENABLED instead of #ifdef.
>> But I've kept a #if IS_ENABLED(...) around the function ubi_rename_vol.
>> Otherwise if this option is not enabled, there is a warning when building :
>> 
>> CC cmd/ubi.o
>> cmd/ubi.c:254:12: warning: 'ubi_rename_vol' defined but not used
>> [-Wunused-function]
>> static int ubi_rename_vol(char *oldname, char *newname)
>> ^~
> 
> Use C
> 
> if (IS_ENABLED(CONFIG_...) && !strcmp(cmd, "rename"))
> 
> not cpp
> 
> #if IS_ENABLED(CONFIG_...)
> if (!strcmp(cmd, "rename"))
> 
> That way the compiler sees ubi_rename_vol is used, but also knows that
> it is dead code that can be eliminated. Less ifdeffery (none, actually),
> and the code in ubi_rename_vol gets compile coverage regardless of
> configuration.

Thanks a lot for this explanation.

I have sent a v4. And it works as expected, without the #if ... before
the function ubi_rename_vol, there isn't a warning if ubi rename is not
enabled in the config.

 
> Rasmus

Regards,
Philippe


[PATCH v4] cmd: ubi: add a command to rename volume

2020-03-23 Thread Philippe Reynes
This commit adds the command ubi rename to rename an ubi volume.
The format of the command is: ubi rename  .
To enable this command, the option CMD_UBI_RENAME must be selected.

Signed-off-by: Philippe Reynes 
---
 cmd/Kconfig |  8 
 cmd/ubi.c   | 39 +++
 2 files changed, 47 insertions(+)

Changelog:
v4:
- fix usage of IS_ENABLED (feedback from Rasmus)
- use ! instead of == 0
v3:
- use IS_ENABLED instead of #ifdef (feedback from Simon)
- fix comment (feedback from Simon)
v2:
- added an option CMD_UBI_RENAME (feedback from Wolfgang)

diff --git a/cmd/Kconfig b/cmd/Kconfig
index 6403bc4..1564694 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -2172,6 +2172,14 @@ config CMD_UBI
  It is also strongly encouraged to also enable CONFIG_MTD to get full
  partition support.
 
+config CMD_UBI_RENAME
+   bool "Enable rename"
+   depends on CMD_UBI
+   default n
+   help
+ Enable a "ubi" command to rename ubi volume:
+  ubi rename  
+
 config CMD_UBIFS
tristate "Enable UBIFS - Unsorted block images filesystem commands"
depends on CMD_UBI
diff --git a/cmd/ubi.c b/cmd/ubi.c
index cecf251..54d128d 100644
--- a/cmd/ubi.c
+++ b/cmd/ubi.c
@@ -251,6 +251,39 @@ out_err:
return err;
 }
 
+static int ubi_rename_vol(char *oldname, char *newname)
+{
+   struct ubi_volume *vol;
+   struct ubi_rename_entry rename;
+   struct ubi_volume_desc desc;
+   struct list_head list;
+
+   vol = ubi_find_volume(oldname);
+   if (!vol) {
+   printf("%s: volume %s doesn't exist\n", __func__, oldname);
+   return ENODEV;
+   }
+
+   printf("Rename UBI volume %s to %s\n", oldname, newname);
+
+   if (ubi->ro_mode) {
+   printf("%s: ubi device is in read-only mode\n", __func__);
+   return EROFS;
+   }
+
+   rename.new_name_len = strlen(newname);
+   strcpy(rename.new_name, newname);
+   rename.remove = 0;
+   desc.vol = vol;
+   desc.mode = 0;
+   rename.desc = &desc;
+   INIT_LIST_HEAD(&rename.list);
+   INIT_LIST_HEAD(&list);
+   list_add(&rename.list, &list);
+
+   return ubi_rename_volumes(ubi, &list);
+}
+
 static int ubi_volume_continue_write(char *volume, void *buf, size_t size)
 {
int err = 1;
@@ -604,6 +637,9 @@ static int do_ubi(cmd_tbl_t *cmdtp, int flag, int argc, 
char * const argv[])
return ubi_remove_vol(argv[2]);
}
 
+   if (IS_ENABLED(CONFIG_CMD_UBI_RENAME) && !strncmp(argv[1], "rename", 6))
+   return ubi_rename_vol(argv[2], argv[3]);
+
if (strncmp(argv[1], "skipcheck", 9) == 0) {
/* E.g., change skip_check flag */
if (argc == 4) {
@@ -692,6 +728,9 @@ U_BOOT_CMD(
" - Read volume to address with size\n"
"ubi remove[vol] volume"
" - Remove volume\n"
+#if IS_ENABLED(CONFIG_CMD_UBI_RENAME)
+   "ubi rename oldname newname\n"
+#endif
"ubi skipcheck volume on/off - Set or clear skip_check flag in volume 
header\n"
"[Legends]\n"
" volume: character name\n"
-- 
2.7.4



Re: [PATCH v2] cmd: ubi: add a command to rename volume

2020-03-23 Thread Philippe REYNES
Hi Simon,

> Hi Philippe,
> 
> On Fri, 20 Mar 2020 at 03:55, Philippe Reynes
>  wrote:
>> 
>> This commit add the command ubi rename to rename an ubi volume.
> 
> adds
> 
>> The format of the command is: ubi rename  .
>> To enable this command, the option CMD_UBI_RENAME must be selected.
>> 
>> Signed-off-by: Philippe Reynes 
>> ---
>> cmd/Kconfig | 8 
>> cmd/ubi.c | 43 +++
>> 2 files changed, 51 insertions(+)
>> 
>> Changelog:
>> v2:
>> - added an option CMD_UBI_RENAME (feedback from Wolfgang)
>> 
>> diff --git a/cmd/Kconfig b/cmd/Kconfig
>> index 6403bc4..1564694 100644
>> --- a/cmd/Kconfig
>> +++ b/cmd/Kconfig
>> @@ -2172,6 +2172,14 @@ config CMD_UBI
>> It is also strongly encouraged to also enable CONFIG_MTD to get full
>> partition support.
>> 
>> +config CMD_UBI_RENAME
>> + bool "Enable rename"
>> + depends on CMD_UBI
>> + default n
>> + help
>> + Enable a "ubi" command to rename ubi volume:
>> + ubi rename  
>> +
>> config CMD_UBIFS
>> tristate "Enable UBIFS - Unsorted block images filesystem commands"
>> depends on CMD_UBI
>> diff --git a/cmd/ubi.c b/cmd/ubi.c
>> index cecf251..4885661 100644
>> --- a/cmd/ubi.c
>> +++ b/cmd/ubi.c
>> @@ -251,6 +251,41 @@ out_err:
>> return err;
>> }
>> 
>> +#ifdef CONFIG_CMD_UBI_RENAME
>> +static int ubi_rename_vol(char *oldname, char *newname)
>> +{
>> + struct ubi_volume *vol;
>> + struct ubi_rename_entry rename;
>> + struct ubi_volume_desc desc;
>> + struct list_head list;
>> +
>> + vol = ubi_find_volume(oldname);
>> + if (!vol) {
>> + printf("%s: volume %s doesn't exist\n", __func__, oldname);
>> + return ENODEV;
>> + }
>> +
>> + printf("Rename UBI volume %s to %s\n", oldname, newname);
>> +
>> + if (ubi->ro_mode) {
>> + printf("%s: ubi device is in read-only mode\n", __func__);
>> + return EROFS;
>> + }
>> +
>> + rename.new_name_len = strlen(newname);
>> + strcpy(rename.new_name, newname);
>> + rename.remove = 0;
>> + desc.vol = vol;
>> + desc.mode = 0;
>> + rename.desc = &desc;
>> + INIT_LIST_HEAD(&rename.list);
>> + INIT_LIST_HEAD(&list);
>> + list_add(&rename.list, &list);
>> +
>> + return ubi_rename_volumes(ubi, &list);
>> +}
>> +#endif /* CONFIG_CMD_UBI_RENAME */
>> +
>> static int ubi_volume_continue_write(char *volume, void *buf, size_t size)
>> {
>> int err = 1;
>> @@ -604,6 +639,11 @@ static int do_ubi(cmd_tbl_t *cmdtp, int flag, int argc,
>> char * const argv[])
>> return ubi_remove_vol(argv[2]);
>> }
>> 
>> +#ifdef CONFIG_CMD_UBI_RENAME
> 
> Can you use IS_ENABLED(CONFIG_...) and drop the #ifdef way above?

I've sent a v3 where I use IS_ENABLED instead of #ifdef.
But I've kept a #if IS_ENABLED(...) around the function ubi_rename_vol.
Otherwise if this option is not enabled, there is a warning when building :

  CC  cmd/ubi.o
cmd/ubi.c:254:12: warning: 'ubi_rename_vol' defined but not used 
[-Wunused-function]
 static int ubi_rename_vol(char *oldname, char *newname)
^~

 
>> + if (strncmp(argv[1], "rename", 6) == 0)
>> + return ubi_rename_vol(argv[2], argv[3]);
>> +#endif
>> +
> [..]
> 
> Regards,
> Simon

Regards,
Philippe


[PATCH v3] cmd: ubi: add a command to rename volume

2020-03-23 Thread Philippe Reynes
This commit adds the command ubi rename to rename an ubi volume.
The format of the command is: ubi rename  .
To enable this command, the option CMD_UBI_RENAME must be selected.

Signed-off-by: Philippe Reynes 
---
 cmd/Kconfig |  8 
 cmd/ubi.c   | 43 +++
 2 files changed, 51 insertions(+)

Changelog:
v3:
- use IS_ENABLED instead of #ifdef (feedback from Simon)
- fix comment (feedback from Simon)
v2:
- added an option CMD_UBI_RENAME (feedback from Wolfgang)

diff --git a/cmd/Kconfig b/cmd/Kconfig
index 6403bc4..1564694 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -2172,6 +2172,14 @@ config CMD_UBI
  It is also strongly encouraged to also enable CONFIG_MTD to get full
  partition support.
 
+config CMD_UBI_RENAME
+   bool "Enable rename"
+   depends on CMD_UBI
+   default n
+   help
+ Enable a "ubi" command to rename ubi volume:
+  ubi rename  
+
 config CMD_UBIFS
tristate "Enable UBIFS - Unsorted block images filesystem commands"
depends on CMD_UBI
diff --git a/cmd/ubi.c b/cmd/ubi.c
index cecf251..c9ae208 100644
--- a/cmd/ubi.c
+++ b/cmd/ubi.c
@@ -251,6 +251,41 @@ out_err:
return err;
 }
 
+#if IS_ENABLED(CONFIG_CMD_UBI_RENAME)
+static int ubi_rename_vol(char *oldname, char *newname)
+{
+   struct ubi_volume *vol;
+   struct ubi_rename_entry rename;
+   struct ubi_volume_desc desc;
+   struct list_head list;
+
+   vol = ubi_find_volume(oldname);
+   if (!vol) {
+   printf("%s: volume %s doesn't exist\n", __func__, oldname);
+   return ENODEV;
+   }
+
+   printf("Rename UBI volume %s to %s\n", oldname, newname);
+
+   if (ubi->ro_mode) {
+   printf("%s: ubi device is in read-only mode\n", __func__);
+   return EROFS;
+   }
+
+   rename.new_name_len = strlen(newname);
+   strcpy(rename.new_name, newname);
+   rename.remove = 0;
+   desc.vol = vol;
+   desc.mode = 0;
+   rename.desc = &desc;
+   INIT_LIST_HEAD(&rename.list);
+   INIT_LIST_HEAD(&list);
+   list_add(&rename.list, &list);
+
+   return ubi_rename_volumes(ubi, &list);
+}
+#endif
+
 static int ubi_volume_continue_write(char *volume, void *buf, size_t size)
 {
int err = 1;
@@ -604,6 +639,11 @@ static int do_ubi(cmd_tbl_t *cmdtp, int flag, int argc, 
char * const argv[])
return ubi_remove_vol(argv[2]);
}
 
+#if IS_ENABLED(CONFIG_CMD_UBI_RENAME)
+   if (strncmp(argv[1], "rename", 6) == 0)
+   return ubi_rename_vol(argv[2], argv[3]);
+#endif
+
if (strncmp(argv[1], "skipcheck", 9) == 0) {
/* E.g., change skip_check flag */
if (argc == 4) {
@@ -692,6 +732,9 @@ U_BOOT_CMD(
" - Read volume to address with size\n"
"ubi remove[vol] volume"
" - Remove volume\n"
+#if IS_ENABLED(CONFIG_CMD_UBI_RENAME)
+   "ubi rename oldname newname\n"
+#endif
"ubi skipcheck volume on/off - Set or clear skip_check flag in volume 
header\n"
"[Legends]\n"
" volume: character name\n"
-- 
2.7.4



[PATCH v2] cmd: ubi: add a command to rename volume

2020-03-20 Thread Philippe Reynes
This commit add the command ubi rename to rename an ubi volume.
The format of the command is: ubi rename  .
To enable this command, the option CMD_UBI_RENAME must be selected.

Signed-off-by: Philippe Reynes 
---
 cmd/Kconfig |  8 
 cmd/ubi.c   | 43 +++
 2 files changed, 51 insertions(+)

Changelog:
v2:
- added an option CMD_UBI_RENAME (feedback from Wolfgang)

diff --git a/cmd/Kconfig b/cmd/Kconfig
index 6403bc4..1564694 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -2172,6 +2172,14 @@ config CMD_UBI
  It is also strongly encouraged to also enable CONFIG_MTD to get full
  partition support.
 
+config CMD_UBI_RENAME
+   bool "Enable rename"
+   depends on CMD_UBI
+   default n
+   help
+ Enable a "ubi" command to rename ubi volume:
+  ubi rename  
+
 config CMD_UBIFS
tristate "Enable UBIFS - Unsorted block images filesystem commands"
depends on CMD_UBI
diff --git a/cmd/ubi.c b/cmd/ubi.c
index cecf251..4885661 100644
--- a/cmd/ubi.c
+++ b/cmd/ubi.c
@@ -251,6 +251,41 @@ out_err:
return err;
 }
 
+#ifdef CONFIG_CMD_UBI_RENAME
+static int ubi_rename_vol(char *oldname, char *newname)
+{
+   struct ubi_volume *vol;
+   struct ubi_rename_entry rename;
+   struct ubi_volume_desc desc;
+   struct list_head list;
+
+   vol = ubi_find_volume(oldname);
+   if (!vol) {
+   printf("%s: volume %s doesn't exist\n", __func__, oldname);
+   return ENODEV;
+   }
+
+   printf("Rename UBI volume %s to %s\n", oldname, newname);
+
+   if (ubi->ro_mode) {
+   printf("%s: ubi device is in read-only mode\n", __func__);
+   return EROFS;
+   }
+
+   rename.new_name_len = strlen(newname);
+   strcpy(rename.new_name, newname);
+   rename.remove = 0;
+   desc.vol = vol;
+   desc.mode = 0;
+   rename.desc = &desc;
+   INIT_LIST_HEAD(&rename.list);
+   INIT_LIST_HEAD(&list);
+   list_add(&rename.list, &list);
+
+   return ubi_rename_volumes(ubi, &list);
+}
+#endif /* CONFIG_CMD_UBI_RENAME */
+
 static int ubi_volume_continue_write(char *volume, void *buf, size_t size)
 {
int err = 1;
@@ -604,6 +639,11 @@ static int do_ubi(cmd_tbl_t *cmdtp, int flag, int argc, 
char * const argv[])
return ubi_remove_vol(argv[2]);
}
 
+#ifdef CONFIG_CMD_UBI_RENAME
+   if (strncmp(argv[1], "rename", 6) == 0)
+   return ubi_rename_vol(argv[2], argv[3]);
+#endif
+
if (strncmp(argv[1], "skipcheck", 9) == 0) {
/* E.g., change skip_check flag */
if (argc == 4) {
@@ -692,6 +732,9 @@ U_BOOT_CMD(
" - Read volume to address with size\n"
"ubi remove[vol] volume"
" - Remove volume\n"
+#ifdef CONFIG_CMD_UBI_RENAME
+   "ubi rename oldname newname\n"
+#endif
"ubi skipcheck volume on/off - Set or clear skip_check flag in volume 
header\n"
"[Legends]\n"
" volume: character name\n"
-- 
2.7.4



Re: [*** MED SPAM ***]Re: [PATCH] cmd: ubi: add a command to rename volume

2020-03-20 Thread Philippe REYNES
Hi Wolfgang,

> Dear Philippe,
> 
> In message <1584644739-10258-1-git-send-email-philippe.rey...@softathome.com>
> you wrote:
>> This commit add the command ubi rename to rename an ubi volume.
>> The format of the command is: ubi rename  .
> 
> Can we plase make this optional / configurable?

Yes, of course, I sent a v2 with an option CMD_UBI_RENAME.
 
> Thanks!
> 
> Wolfgang Denk

Regards,
Philippe


[PATCH] cmd: ubi: add a command to rename volume

2020-03-19 Thread Philippe Reynes
This commit add the command ubi rename to rename an ubi volume.
The format of the command is: ubi rename  .

Signed-off-by: Philippe Reynes 
---
 cmd/ubi.c | 37 +
 1 file changed, 37 insertions(+)

diff --git a/cmd/ubi.c b/cmd/ubi.c
index cecf251..424f555 100644
--- a/cmd/ubi.c
+++ b/cmd/ubi.c
@@ -251,6 +251,39 @@ out_err:
return err;
 }
 
+static int ubi_rename_vol(char *oldname, char *newname)
+{
+   struct ubi_volume *vol;
+   struct ubi_rename_entry rename;
+   struct ubi_volume_desc desc;
+   struct list_head list;
+
+   vol = ubi_find_volume(oldname);
+   if (!vol) {
+   printf("%s: volume %s doesn't exist\n", __func__, oldname);
+   return ENODEV;
+   }
+
+   printf("Rename UBI volume %s to %s\n", oldname, newname);
+
+   if (ubi->ro_mode) {
+   printf("%s: ubi device is in read-only mode\n", __func__);
+   return EROFS;
+   }
+
+   rename.new_name_len = strlen(newname);
+   strcpy(rename.new_name, newname);
+   rename.remove = 0;
+   desc.vol = vol;
+   desc.mode = 0;
+   rename.desc = &desc;
+   INIT_LIST_HEAD(&rename.list);
+   INIT_LIST_HEAD(&list);
+   list_add(&rename.list, &list);
+
+   return ubi_rename_volumes(ubi, &list);
+}
+
 static int ubi_volume_continue_write(char *volume, void *buf, size_t size)
 {
int err = 1;
@@ -604,6 +637,9 @@ static int do_ubi(cmd_tbl_t *cmdtp, int flag, int argc, 
char * const argv[])
return ubi_remove_vol(argv[2]);
}
 
+   if (strncmp(argv[1], "rename", 6) == 0)
+   return ubi_rename_vol(argv[2], argv[3]);
+
if (strncmp(argv[1], "skipcheck", 9) == 0) {
/* E.g., change skip_check flag */
if (argc == 4) {
@@ -693,6 +729,7 @@ U_BOOT_CMD(
"ubi remove[vol] volume"
" - Remove volume\n"
"ubi skipcheck volume on/off - Set or clear skip_check flag in volume 
header\n"
+   "ubi rename oldname newname\n"
"[Legends]\n"
" volume: character name\n"
" size: specified in bytes\n"
-- 
2.7.4



Re: [PATCH v2 12/14] image: Use constants for 'required' and 'key-name-hint'

2020-03-18 Thread Philippe REYNES



> Objet: [PATCH v2 12/14] image: Use constants for 'required' and 
> 'key-name-hint'

> These are used in multiple places so update them to use a shared #define.
> 
> Signed-off-by: Simon Glass 

Reviewed-by: Philippe Reynes 

> ---
> 
> Changes in v2: None
> 
> common/image-cipher.c | 2 +-
> common/image-fit.c | 6 +++---
> common/image-sig.c | 8 +---
> include/image.h | 4 +++-
> lib/rsa/rsa-sign.c | 6 +++---
> tools/image-host.c | 8 
> 6 files changed, 19 insertions(+), 15 deletions(-)
> 
> diff --git a/common/image-cipher.c b/common/image-cipher.c
> index cee3b03ee5..f50c3d31bd 100644
> --- a/common/image-cipher.c
> +++ b/common/image-cipher.c
> @@ -88,7 +88,7 @@ static int fit_image_setup_decrypt(struct image_cipher_info
> *info,
> return -1;
> }
> 
> - info->keyname = fdt_getprop(fit, cipher_noffset, "key-name-hint", NULL);
> + info->keyname = fdt_getprop(fit, cipher_noffset, FIT_KEY_HINT, NULL);
> if (!info->keyname) {
> printf("Can't get key name\n");
> return -1;
> diff --git a/common/image-fit.c b/common/image-fit.c
> index a5c85ede8d..c8ff77526c 100644
> --- a/common/image-fit.c
> +++ b/common/image-fit.c
> @@ -168,7 +168,7 @@ static void fit_image_print_data(const void *fit, int
> noffset, const char *p,
> int value_len;
> char *algo;
> const char *padding;
> - int required;
> + bool required;
> int ret, i;
> 
> debug("%s %s node: '%s'\n", p, type,
> @@ -179,8 +179,8 @@ static void fit_image_print_data(const void *fit, int
> noffset, const char *p,
> return;
> }
> printf("%s", algo);
> - keyname = fdt_getprop(fit, noffset, "key-name-hint", NULL);
> - required = fdt_getprop(fit, noffset, "required", NULL) != NULL;
> + keyname = fdt_getprop(fit, noffset, FIT_KEY_HINT, NULL);
> + required = fdt_getprop(fit, noffset, FIT_KEY_REQUIRED, NULL) != NULL;
> if (keyname)
> printf(":%s", keyname);
> if (required)
> diff --git a/common/image-sig.c b/common/image-sig.c
> index 03143a4040..6563effcf3 100644
> --- a/common/image-sig.c
> +++ b/common/image-sig.c
> @@ -229,7 +229,7 @@ static int fit_image_setup_verify(struct image_sign_info
> *info,
> padding_name = RSA_DEFAULT_PADDING_NAME;
> 
> memset(info, '\0', sizeof(*info));
> - info->keyname = fdt_getprop(fit, noffset, "key-name-hint", NULL);
> + info->keyname = fdt_getprop(fit, noffset, FIT_KEY_HINT, NULL);
> info->fit = (void *)fit;
> info->node_offset = noffset;
> info->name = algo_name;
> @@ -340,7 +340,8 @@ int fit_image_verify_required_sigs(const void *fit, int
> image_noffset,
> const char *required;
> int ret;
> 
> - required = fdt_getprop(sig_blob, noffset, "required", NULL);
> + required = fdt_getprop(sig_blob, noffset, FIT_KEY_REQUIRED,
> + NULL);
> if (!required || strcmp(required, "image"))
> continue;
> ret = fit_image_verify_sig(fit, image_noffset, data, size,
> @@ -557,7 +558,8 @@ int fit_config_verify_required_sigs(const void *fit, int
> conf_noffset,
> const char *required;
> int ret;
> 
> - required = fdt_getprop(sig_blob, noffset, "required", NULL);
> + required = fdt_getprop(sig_blob, noffset, FIT_KEY_REQUIRED,
> + NULL);
> if (!required || strcmp(required, "conf"))
> continue;
> ret = fit_config_verify_sig(fit, conf_noffset, sig_blob,
> diff --git a/include/image.h b/include/image.h
> index 512243f159..3ffc0fdd68 100644
> --- a/include/image.h
> +++ b/include/image.h
> @@ -939,12 +939,14 @@ int booti_setup(ulong image, ulong *relocated_addr, 
> ulong
> *size,
> #define FIT_IMAGES_PATH "/images"
> #define FIT_CONFS_PATH "/configurations"
> 
> -/* hash/signature node */
> +/* hash/signature/key node */
> #define FIT_HASH_NODENAME "hash"
> #define FIT_ALGO_PROP "algo"
> #define FIT_VALUE_PROP "value"
> #define FIT_IGNORE_PROP "uboot-ignore"
> #define FIT_SIG_NODENAME "signature"
> +#define FIT_KEY_REQUIRED "required"
> +#define FIT_KEY_HINT "key-name-hint"
> 
> /* cipher node */
> #define FIT_CIPHER_NODENAME "cipher"
> diff --git a/lib/rsa/rsa-sign.c b/lib/rsa/rsa-sign.c
> index 6400ef63d6..580c744709 100644
> --- a/lib/rsa/rsa-sign.c
> +++ b/lib/rsa/rsa-sign.c
> @@ -792,8 +792,8 @@ int rsa_add_verify_data(struct image_sign_info *info, void
> *keydest)
> }
> 
> if (!ret) {
> - ret = fdt_setprop_string(keydest, node, "key-name-hint",
> - info->keyname);
> + ret = fdt_setprop_string(keydest, node, FIT_KEY_HINT,
> + info->keyname);
> 

Re: [PATCH 2/3] configs: use unified bcmbca nand controller

2020-03-09 Thread Philippe REYNES



> Objet: [PATCH 2/3] configs: use unified bcmbca nand controller


> Signed-off-by: Nicolas Heemeryck 
> Cc: Philippe Reynes 

Reviewed-by: Philippe Reynes 

> ---
> configs/bcm963158_ram_defconfig | 2 +-
> configs/bcm968360bg_ram_defconfig | 2 +-
> configs/bcm968580xref_ram_defconfig | 2 +-
> 3 files changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/configs/bcm963158_ram_defconfig b/configs/bcm963158_ram_defconfig
> index 5cf32d52cf..91722384f8 100644
> --- a/configs/bcm963158_ram_defconfig
> +++ b/configs/bcm963158_ram_defconfig
> @@ -40,7 +40,7 @@ CONFIG_MTD=y
> CONFIG_DM_MTD=y
> CONFIG_MTD_RAW_NAND=y
> CONFIG_NAND_BRCMNAND=y
> -CONFIG_NAND_BRCMNAND_63158=y
> +CONFIG_NAND_BRCMNAND_BCMBCA=y
> CONFIG_DM_SPI_FLASH=y
> CONFIG_SPI_FLASH_MACRONIX=y
> CONFIG_SPECIFY_CONSOLE_INDEX=y
> diff --git a/configs/bcm968360bg_ram_defconfig
> b/configs/bcm968360bg_ram_defconfig
> index bc3134ff29..e0fe8fa7fe 100644
> --- a/configs/bcm968360bg_ram_defconfig
> +++ b/configs/bcm968360bg_ram_defconfig
> @@ -36,7 +36,7 @@ CONFIG_MTD=y
> CONFIG_DM_MTD=y
> CONFIG_MTD_RAW_NAND=y
> CONFIG_NAND_BRCMNAND=y
> -CONFIG_NAND_BRCMNAND_68360=y
> +CONFIG_NAND_BRCMNAND_BCMBCA=y
> CONFIG_DM_SPI_FLASH=y
> CONFIG_SPI_FLASH_SFDP_SUPPORT=y
> CONFIG_SPI_FLASH_MACRONIX=y
> diff --git a/configs/bcm968580xref_ram_defconfig
> b/configs/bcm968580xref_ram_defconfig
> index c158a7c47c..9cc527d2ce 100644
> --- a/configs/bcm968580xref_ram_defconfig
> +++ b/configs/bcm968580xref_ram_defconfig
> @@ -36,7 +36,7 @@ CONFIG_MTD=y
> CONFIG_DM_MTD=y
> CONFIG_MTD_RAW_NAND=y
> CONFIG_NAND_BRCMNAND=y
> -CONFIG_NAND_BRCMNAND_6858=y
> +CONFIG_NAND_BRCMNAND_BCMBCA=y
> CONFIG_DM_SPI_FLASH=y
> CONFIG_SPI_FLASH_SFDP_SUPPORT=y
> CONFIG_SPI_FLASH_MACRONIX=y
> --
> 2.20.1


Re: [PATCH 3/3] brcmnand: drop arch specific nand controller

2020-03-09 Thread Philippe REYNES



> Objet: [PATCH 3/3] brcmnand: drop arch specific nand controller

> Use instead the unified bcmbca controller.
> 
> Signed-off-by: Nicolas Heemeryck 
> Cc: Philippe Reynes 

Reviewed-by: Philippe Reynes 

> ---
> drivers/mtd/nand/raw/Kconfig | 18 ---
> drivers/mtd/nand/raw/brcmnand/Makefile | 3 -
> drivers/mtd/nand/raw/brcmnand/bcm63158_nand.c | 124 --
> drivers/mtd/nand/raw/brcmnand/bcm68360_nand.c | 123 -
> drivers/mtd/nand/raw/brcmnand/bcm6858_nand.c | 124 --
> 5 files changed, 392 deletions(-)
> delete mode 100644 drivers/mtd/nand/raw/brcmnand/bcm63158_nand.c
> delete mode 100644 drivers/mtd/nand/raw/brcmnand/bcm68360_nand.c
> delete mode 100644 drivers/mtd/nand/raw/brcmnand/bcm6858_nand.c
> 
> diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig
> index c37e2e96c2..02e00e3fe6 100644
> --- a/drivers/mtd/nand/raw/Kconfig
> +++ b/drivers/mtd/nand/raw/Kconfig
> @@ -78,30 +78,12 @@ config NAND_BRCMNAND_6368
> help
> Enable support for broadcom nand driver on bcm6368.
> 
> -config NAND_BRCMNAND_68360
> - bool "Support Broadcom NAND controller on bcm68360"
> - depends on NAND_BRCMNAND && ARCH_BCM68360
> - help
> - Enable support for broadcom nand driver on bcm68360.
> -
> config NAND_BRCMNAND_6838
> bool "Support Broadcom NAND controller on bcm6838"
> depends on NAND_BRCMNAND && ARCH_BMIPS && SOC_BMIPS_BCM6838
> help
> Enable support for broadcom nand driver on bcm6838.
> 
> -config NAND_BRCMNAND_6858
> - bool "Support Broadcom NAND controller on bcm6858"
> - depends on NAND_BRCMNAND && ARCH_BCM6858
> - help
> - Enable support for broadcom nand driver on bcm6858.
> -
> -config NAND_BRCMNAND_63158
> - bool "Support Broadcom NAND controller on bcm63158"
> - depends on NAND_BRCMNAND && ARCH_BCM63158
> - help
> - Enable support for broadcom nand driver on bcm63158.
> -
> config NAND_BRCMNAND_BCMBCA
> bool "Support Broadcom NAND controller for BCA platforms"
> depends on NAND_BRCMNAND && (ARM64 || CPU_V7A)
> diff --git a/drivers/mtd/nand/raw/brcmnand/Makefile
> b/drivers/mtd/nand/raw/brcmnand/Makefile
> index 61203bf5ff..ad9e1d50a6 100644
> --- a/drivers/mtd/nand/raw/brcmnand/Makefile
> +++ b/drivers/mtd/nand/raw/brcmnand/Makefile
> @@ -1,10 +1,7 @@
> # SPDX-License-Identifier: GPL-2.0+
> 
> obj-$(CONFIG_NAND_BRCMNAND_6368) += bcm6368_nand.o
> -obj-$(CONFIG_NAND_BRCMNAND_63158) += bcm63158_nand.o
> -obj-$(CONFIG_NAND_BRCMNAND_68360) += bcm68360_nand.o
> obj-$(CONFIG_NAND_BRCMNAND_6838) += bcm6838_nand.o
> -obj-$(CONFIG_NAND_BRCMNAND_6858) += bcm6858_nand.o
> obj-$(CONFIG_NAND_BRCMNAND_BCMBCA) += bcmbca_nand.o
> obj-$(CONFIG_NAND_BRCMNAND) += brcmnand.o
> obj-$(CONFIG_NAND_BRCMNAND) += brcmnand_compat.o
> diff --git a/drivers/mtd/nand/raw/brcmnand/bcm63158_nand.c
> b/drivers/mtd/nand/raw/brcmnand/bcm63158_nand.c
> deleted file mode 100644
> index ea7c65a1f6..00
> --- a/drivers/mtd/nand/raw/brcmnand/bcm63158_nand.c
> +++ /dev/null
> @@ -1,124 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0+
> -
> -#include 
> -#include 
> -#include 
> -#include 
> -#include 
> -#include 
> -#include 
> -#include 
> -#include 
> -
> -#include "brcmnand.h"
> -
> -struct bcm63158_nand_soc {
> - struct brcmnand_soc soc;
> - void __iomem *base;
> -};
> -
> -#define BCM63158_NAND_INT 0x00
> -#define BCM63158_NAND_STATUS_SHIFT 0
> -#define BCM63158_NAND_STATUS_MASK (0xfff << BCM63158_NAND_STATUS_SHIFT)
> -
> -#define BCM63158_NAND_INT_EN 0x04
> -#define BCM63158_NAND_ENABLE_SHIFT 0
> -#define BCM63158_NAND_ENABLE_MASK (0x << BCM63158_NAND_ENABLE_SHIFT)
> -
> -enum {
> - BCM63158_NP_READ = BIT(0),
> - BCM63158_BLOCK_ERASE = BIT(1),
> - BCM63158_COPY_BACK = BIT(2),
> - BCM63158_PAGE_PGM = BIT(3),
> - BCM63158_CTRL_READY = BIT(4),
> - BCM63158_DEV_RBPIN = BIT(5),
> - BCM63158_ECC_ERR_UNC = BIT(6),
> - BCM63158_ECC_ERR_CORR = BIT(7),
> -};
> -
> -static bool bcm63158_nand_intc_ack(struct brcmnand_soc *soc)
> -{
> - struct bcm63158_nand_soc *priv =
> - container_of(soc, struct bcm63158_nand_soc, soc);
> - void __iomem *mmio = priv->base + BCM63158_NAND_INT;
> - u32 val = brcmnand_readl(mmio);
> -
> - if (val & (BCM63158_CTRL_READY << BCM63158_NAND_STATUS_SHIFT)) {
> - /* Ack interrupt */
> - val &= ~BCM63158_NAND_STATUS_MASK;
> - val |= BCM63158_CTRL_READY << BCM63158_NAND_STATUS_SHIFT;
> - brcmnand_writel(val, mmio);
> - return true;
> - }
> -
> - return false;
> -}
> -
> -static void bcm63158_nand_intc_set(struct brcmnand_soc

Re: [PATCH 1/3] nand: brcmnand: add bcmbca support

2020-03-09 Thread Philippe REYNES



> Almost all Broadcom BCA (Broadband Carrier Access) platforms based on
> ARM use the same nand controller.
> So rather than adding a bcm6xxx_nand.c per Broadcom SoC, use a unified
> nand controller based on the existing one and selectable through
> NAND_BRCMNAND_BCMBCA.
> 
> The bcmbca controller should support all ARM based bcm63xxx, bcm68xx,
> bcm67xx and bcm490x SoCs.
> 
> Signed-off-by: Nicolas Heemeryck 
> Cc: Philippe Reynes 

Reviewed-by: Philippe Reynes 

> ---
> drivers/mtd/nand/raw/Kconfig | 6 +
> drivers/mtd/nand/raw/brcmnand/Makefile | 1 +
> drivers/mtd/nand/raw/brcmnand/bcmbca_nand.c | 124 
> 3 files changed, 131 insertions(+)
> create mode 100644 drivers/mtd/nand/raw/brcmnand/bcmbca_nand.c
> 
> diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig
> index 23201ca720..c37e2e96c2 100644
> --- a/drivers/mtd/nand/raw/Kconfig
> +++ b/drivers/mtd/nand/raw/Kconfig
> @@ -102,6 +102,12 @@ config NAND_BRCMNAND_63158
> help
> Enable support for broadcom nand driver on bcm63158.
> 
> +config NAND_BRCMNAND_BCMBCA
> + bool "Support Broadcom NAND controller for BCA platforms"
> + depends on NAND_BRCMNAND && (ARM64 || CPU_V7A)
> + help
> + Enable support for broadcom nand driver for BCA platforms.
> +
> config NAND_DAVINCI
> bool "Support TI Davinci NAND controller"
> help
> diff --git a/drivers/mtd/nand/raw/brcmnand/Makefile
> b/drivers/mtd/nand/raw/brcmnand/Makefile
> index 5d9e7e3f3b..61203bf5ff 100644
> --- a/drivers/mtd/nand/raw/brcmnand/Makefile
> +++ b/drivers/mtd/nand/raw/brcmnand/Makefile
> @@ -5,5 +5,6 @@ obj-$(CONFIG_NAND_BRCMNAND_63158) += bcm63158_nand.o
> obj-$(CONFIG_NAND_BRCMNAND_68360) += bcm68360_nand.o
> obj-$(CONFIG_NAND_BRCMNAND_6838) += bcm6838_nand.o
> obj-$(CONFIG_NAND_BRCMNAND_6858) += bcm6858_nand.o
> +obj-$(CONFIG_NAND_BRCMNAND_BCMBCA) += bcmbca_nand.o
> obj-$(CONFIG_NAND_BRCMNAND) += brcmnand.o
> obj-$(CONFIG_NAND_BRCMNAND) += brcmnand_compat.o
> diff --git a/drivers/mtd/nand/raw/brcmnand/bcmbca_nand.c
> b/drivers/mtd/nand/raw/brcmnand/bcmbca_nand.c
> new file mode 100644
> index 00..91b0a33397
> --- /dev/null
> +++ b/drivers/mtd/nand/raw/brcmnand/bcmbca_nand.c
> @@ -0,0 +1,124 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "brcmnand.h"
> +
> +struct bcmbca_nand_soc {
> + struct brcmnand_soc soc;
> + void __iomem *base;
> +};
> +
> +#define BCMBCA_NAND_INT 0x00
> +#define BCMBCA_NAND_STATUS_SHIFT 0
> +#define BCMBCA_NAND_STATUS_MASK (0xfff << BCMBCA_NAND_STATUS_SHIFT)
> +
> +#define BCMBCA_NAND_INT_EN 0x04
> +#define BCMBCA_NAND_ENABLE_SHIFT 0
> +#define BCMBCA_NAND_ENABLE_MASK (0x << BCMBCA_NAND_ENABLE_SHIFT)
> +
> +enum {
> + BCMBCA_NP_READ = BIT(0),
> + BCMBCA_BLOCK_ERASE = BIT(1),
> + BCMBCA_COPY_BACK = BIT(2),
> + BCMBCA_PAGE_PGM = BIT(3),
> + BCMBCA_CTRL_READY = BIT(4),
> + BCMBCA_DEV_RBPIN = BIT(5),
> + BCMBCA_ECC_ERR_UNC = BIT(6),
> + BCMBCA_ECC_ERR_CORR = BIT(7),
> +};
> +
> +static bool bcmbca_nand_intc_ack(struct brcmnand_soc *soc)
> +{
> + struct bcmbca_nand_soc *priv =
> + container_of(soc, struct bcmbca_nand_soc, soc);
> + void __iomem *mmio = priv->base + BCMBCA_NAND_INT;
> + u32 val = brcmnand_readl(mmio);
> +
> + if (val & (BCMBCA_CTRL_READY << BCMBCA_NAND_STATUS_SHIFT)) {
> + /* Ack interrupt */
> + val &= ~BCMBCA_NAND_STATUS_MASK;
> + val |= BCMBCA_CTRL_READY << BCMBCA_NAND_STATUS_SHIFT;
> + brcmnand_writel(val, mmio);
> + return true;
> + }
> +
> + return false;
> +}
> +
> +static void bcmbca_nand_intc_set(struct brcmnand_soc *soc, bool en)
> +{
> + struct bcmbca_nand_soc *priv =
> + container_of(soc, struct bcmbca_nand_soc, soc);
> + void __iomem *mmio = priv->base + BCMBCA_NAND_INT_EN;
> + u32 val = brcmnand_readl(mmio);
> +
> + /* Don't ack any interrupts */
> + val &= ~BCMBCA_NAND_STATUS_MASK;
> +
> + if (en)
> + val |= BCMBCA_CTRL_READY << BCMBCA_NAND_ENABLE_SHIFT;
> + else
> + val &= ~(BCMBCA_CTRL_READY << BCMBCA_NAND_ENABLE_SHIFT);
> +
> + brcmnand_writel(val, mmio);
> +}
> +
> +static int bcmbca_nand_probe(struct udevice *dev)
> +{
> + struct udevice *pdev = dev;
> + struct bcmbca_nand_soc *priv = dev_get_priv(dev);
> + struct brcmnand_soc *soc;
> + struct resource res;
> +
> + soc = &priv->soc;
> +
> + dev_read_resource_byname(pdev, "nand-int-base", &res);
> + priv->base = devm_ioremap(dev, res.start, resource_size(&res));
> + i

[PATCH 6/6] bcm96750ref1: add initial support

2020-03-06 Thread Philippe Reynes
This add the initial support of the broadcom reference
board bcm968360bg with a bcm68360 SoC.

This board has 1 GB of RAM, 512 MB of flash (nand),
2 USB port, 1 UART, and 4 ethernet ports.

Signed-off-by: Philippe Reynes 
---
 arch/arm/Kconfig   |  1 +
 arch/arm/dts/Makefile  |  3 ++
 arch/arm/dts/bcm96750ref1.dts  | 78 ++
 board/broadcom/bcm96750ref1/Kconfig| 16 ++
 board/broadcom/bcm96750ref1/MAINTAINERS|  6 +++
 board/broadcom/bcm96750ref1/Makefile   |  3 ++
 board/broadcom/bcm96750ref1/bcm96750ref1.c | 44 +
 configs/bcm96750ref1_ram_defconfig | 68 ++
 include/configs/broadcom_bcm96750ref1.h| 40 +++
 9 files changed, 259 insertions(+)
 create mode 100644 arch/arm/dts/bcm96750ref1.dts
 create mode 100644 board/broadcom/bcm96750ref1/Kconfig
 create mode 100644 board/broadcom/bcm96750ref1/MAINTAINERS
 create mode 100644 board/broadcom/bcm96750ref1/Makefile
 create mode 100644 board/broadcom/bcm96750ref1/bcm96750ref1.c
 create mode 100644 configs/bcm96750ref1_ram_defconfig
 create mode 100644 include/configs/broadcom_bcm96750ref1.h

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 568b95a..a3e9130 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1839,6 +1839,7 @@ source "board/broadcom/bcm23550_w1d/Kconfig"
 source "board/broadcom/bcm28155_ap/Kconfig"
 source "board/broadcom/bcm963158/Kconfig"
 source "board/broadcom/bcm968360bg/Kconfig"
+source "board/broadcom/bcm96750ref1/Kconfig"
 source "board/broadcom/bcm968580xref/Kconfig"
 source "board/broadcom/bcmcygnus/Kconfig"
 source "board/broadcom/bcmnsp/Kconfig"
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 9c593b2..e3dcd89 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -871,6 +871,9 @@ dtb-$(CONFIG_ARCH_BCM63158) += \
 dtb-$(CONFIG_ARCH_BCM68360) += \
bcm968360bg.dtb
 
+dtb-$(CONFIG_ARCH_BCM6750) += \
+   bcm96750ref1.dtb
+
 dtb-$(CONFIG_ARCH_BCM6858) += \
bcm968580xref.dtb
 
diff --git a/arch/arm/dts/bcm96750ref1.dts b/arch/arm/dts/bcm96750ref1.dts
new file mode 100644
index 000..ac607b4
--- /dev/null
+++ b/arch/arm/dts/bcm96750ref1.dts
@@ -0,0 +1,78 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 Philippe Reynes 
+ */
+
+/dts-v1/;
+
+#include "bcm6750.dtsi"
+
+/ {
+   model = "Broadcom bcm6750ref1";
+   compatible = "broadcom,bcm6750ref1", "brcm,bcm6750";
+
+   aliases {
+   serial0 = &uart0;
+   };
+
+   chosen {
+   stdout-path = "serial0:115200n8";
+   };
+
+   memory {
+   device_type = "memory";
+   reg = <0x0 0x4000>;
+   };
+};
+
+&uart0 {
+   u-boot,dm-pre-reloc;
+   status = "okay";
+};
+
+&gpio0 {
+   status = "okay";
+};
+
+&gpio1 {
+   status = "okay";
+};
+
+&gpio2 {
+   status = "okay";
+};
+
+&gpio3 {
+   status = "okay";
+};
+
+&gpio4 {
+   status = "okay";
+};
+
+&gpio5 {
+   status = "okay";
+};
+
+&gpio6 {
+   status = "okay";
+};
+
+&gpio7 {
+   status = "okay";
+};
+
+&nand {
+   status = "okay";
+   write-protect = <0>;
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   nandcs@0 {
+   compatible = "brcm,nandcs";
+   reg = <0>;
+   nand-ecc-strength = <8>;
+   nand-ecc-step-size = <512>;
+   brcm,nand-oob-sector-size = <27>;
+   };
+};
diff --git a/board/broadcom/bcm96750ref1/Kconfig 
b/board/broadcom/bcm96750ref1/Kconfig
new file mode 100644
index 000..e76e2be
--- /dev/null
+++ b/board/broadcom/bcm96750ref1/Kconfig
@@ -0,0 +1,16 @@
+if ARCH_BCM6750
+
+config SYS_VENDOR
+   default "broadcom"
+
+config SYS_BOARD
+   default "bcm96750ref1"
+
+config SYS_CONFIG_NAME
+   default "broadcom_bcm96750ref1"
+
+endif
+
+config TARGET_BCM96750REF1
+   bool "Support Broadcom bcm96750ref1"
+   depends on ARCH_BCM6750
diff --git a/board/broadcom/bcm96750ref1/MAINTAINERS 
b/board/broadcom/bcm96750ref1/MAINTAINERS
new file mode 100644
index 000..e7a5c9c
--- /dev/null
+++ b/board/broadcom/bcm96750ref1/MAINTAINERS
@@ -0,0 +1,6 @@
+BCM96750REF1 BOARD
+M: Philippe Reynes 
+S: Maintained
+F: board/broadcom/bcm96750ref1
+F: include/configs/broadcom_bcm96750ref1.h
+F: configs/bcm96750ref1_ram_defconfig
diff --git a/board/broadcom/bcm96750ref1/Makefile 
b/board/broadcom/bcm96750ref1/Makefile
new file mode 100644
index 000..ac4ffae
--- /dev/null
+++ 

[PATCH 3/6] gpio: bcm6345: allow to use this driver on arm bcm6750

2020-03-06 Thread Philippe Reynes
This IP is also used on some arm SoC, so we allow to
use it on arm bcm6750 too.

Signed-off-by: Philippe Reynes 
---
 drivers/gpio/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index f751a8b..3a595b8 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -55,7 +55,7 @@ config ALTERA_PIO
 
 config BCM6345_GPIO
bool "BCM6345 GPIO driver"
-   depends on DM_GPIO && (ARCH_BMIPS || ARCH_BCM68360 || \
+   depends on DM_GPIO && (ARCH_BMIPS || ARCH_BCM6750 || ARCH_BCM68360 || \
   ARCH_BCM6858 || ARCH_BCM63158)
help
  This driver supports the GPIO banks on BCM6345 SoCs.
-- 
2.7.4



[PATCH 4/6] nand: brcmnand: add bcm6750 support

2020-03-06 Thread Philippe Reynes
This adds the nand support for chipset bcm6750.

Signed-off-by: Philippe Reynes 
---
 drivers/mtd/nand/raw/Kconfig |   6 ++
 drivers/mtd/nand/raw/brcmnand/Makefile   |   1 +
 drivers/mtd/nand/raw/brcmnand/bcm6750_nand.c | 123 +++
 3 files changed, 130 insertions(+)
 create mode 100644 drivers/mtd/nand/raw/brcmnand/bcm6750_nand.c

diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig
index 23201ca..3912337 100644
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
@@ -78,6 +78,12 @@ config NAND_BRCMNAND_6368
help
  Enable support for broadcom nand driver on bcm6368.
 
+config NAND_BRCMNAND_6750
+   bool "Support Broadcom NAND controller on bcm6750"
+   depends on NAND_BRCMNAND && ARCH_BCM6750
+   help
+ Enable support for broadcom nand driver on bcm6750.
+
 config NAND_BRCMNAND_68360
bool "Support Broadcom NAND controller on bcm68360"
depends on NAND_BRCMNAND && ARCH_BCM68360
diff --git a/drivers/mtd/nand/raw/brcmnand/Makefile 
b/drivers/mtd/nand/raw/brcmnand/Makefile
index 5d9e7e3..d3b7325 100644
--- a/drivers/mtd/nand/raw/brcmnand/Makefile
+++ b/drivers/mtd/nand/raw/brcmnand/Makefile
@@ -2,6 +2,7 @@
 
 obj-$(CONFIG_NAND_BRCMNAND_6368) += bcm6368_nand.o
 obj-$(CONFIG_NAND_BRCMNAND_63158) += bcm63158_nand.o
+obj-$(CONFIG_NAND_BRCMNAND_6750) += bcm6750_nand.o
 obj-$(CONFIG_NAND_BRCMNAND_68360) += bcm68360_nand.o
 obj-$(CONFIG_NAND_BRCMNAND_6838) += bcm6838_nand.o
 obj-$(CONFIG_NAND_BRCMNAND_6858) += bcm6858_nand.o
diff --git a/drivers/mtd/nand/raw/brcmnand/bcm6750_nand.c 
b/drivers/mtd/nand/raw/brcmnand/bcm6750_nand.c
new file mode 100644
index 000..22355fb
--- /dev/null
+++ b/drivers/mtd/nand/raw/brcmnand/bcm6750_nand.c
@@ -0,0 +1,123 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "brcmnand.h"
+
+struct bcm6750_nand_soc {
+   struct brcmnand_soc soc;
+   void __iomem *base;
+};
+
+#define BCM6750_NAND_INT   0x00
+#define BCM6750_NAND_STATUS_SHIFT  0
+#define BCM6750_NAND_STATUS_MASK   (0xfff << BCM6750_NAND_STATUS_SHIFT)
+
+#define BCM6750_NAND_INT_EN0x04
+#define BCM6750_NAND_ENABLE_SHIFT  0
+#define BCM6750_NAND_ENABLE_MASK   (0x << BCM6750_NAND_ENABLE_SHIFT)
+
+enum {
+   BCM6750_NP_READ = BIT(0),
+   BCM6750_BLOCK_ERASE = BIT(1),
+   BCM6750_COPY_BACK   = BIT(2),
+   BCM6750_PAGE_PGM= BIT(3),
+   BCM6750_CTRL_READY  = BIT(4),
+   BCM6750_DEV_RBPIN   = BIT(5),
+   BCM6750_ECC_ERR_UNC = BIT(6),
+   BCM6750_ECC_ERR_CORR= BIT(7),
+};
+
+static bool bcm6750_nand_intc_ack(struct brcmnand_soc *soc)
+{
+   struct bcm6750_nand_soc *priv =
+   container_of(soc, struct bcm6750_nand_soc, soc);
+   void __iomem *mmio = priv->base + BCM6750_NAND_INT;
+   u32 val = brcmnand_readl(mmio);
+
+   if (val & (BCM6750_CTRL_READY << BCM6750_NAND_STATUS_SHIFT)) {
+   /* Ack interrupt */
+   val &= ~BCM6750_NAND_STATUS_MASK;
+   val |= BCM6750_CTRL_READY << BCM6750_NAND_STATUS_SHIFT;
+   brcmnand_writel(val, mmio);
+   return true;
+   }
+
+   return false;
+}
+
+static void bcm6750_nand_intc_set(struct brcmnand_soc *soc, bool en)
+{
+   struct bcm6750_nand_soc *priv =
+   container_of(soc, struct bcm6750_nand_soc, soc);
+   void __iomem *mmio = priv->base + BCM6750_NAND_INT_EN;
+   u32 val = brcmnand_readl(mmio);
+
+   /* Don't ack any interrupts */
+   val &= ~BCM6750_NAND_STATUS_MASK;
+
+   if (en)
+   val |= BCM6750_CTRL_READY << BCM6750_NAND_ENABLE_SHIFT;
+   else
+   val &= ~(BCM6750_CTRL_READY << BCM6750_NAND_ENABLE_SHIFT);
+
+   brcmnand_writel(val, mmio);
+}
+
+static int bcm6750_nand_probe(struct udevice *dev)
+{
+   struct udevice *pdev = dev;
+   struct bcm6750_nand_soc *priv = dev_get_priv(dev);
+   struct brcmnand_soc *soc;
+   struct resource res;
+
+   soc = &priv->soc;
+
+   dev_read_resource_byname(pdev, "nand-int-base", &res);
+   priv->base = devm_ioremap(dev, res.start, resource_size(&res));
+   if (IS_ERR(priv->base))
+   return PTR_ERR(priv->base);
+
+   soc->ctlrdy_ack = bcm6750_nand_intc_ack;
+   soc->ctlrdy_set_enabled = bcm6750_nand_intc_set;
+
+   /* Disable and ack all interrupts  */
+   brcmnand_writel(0, priv->base + BCM6750_NAND_INT_EN);
+   brcmnand_writel(0, priv->base + BCM6750_NAND_INT);
+
+   return brcmnand_probe(pdev, soc);
+}
+
+static const struct udevice_id bcm6750_nand_dt_ids[] = {
+   {
+   .compatible = "brcm,nand-bc

[PATCH 5/6] watchdog: bcm6345: allow to use this driver on arm bcm6750

2020-03-06 Thread Philippe Reynes
This IP is also used on some arm SoC, so we allow to
use it on arm bcm6750 too.

Signed-off-by: Philippe Reynes 
---
 drivers/watchdog/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index d24c1e4..2dca5f6 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -93,7 +93,7 @@ config WDT_AT91
 
 config WDT_BCM6345
bool "BCM6345 watchdog timer support"
-   depends on WDT && (ARCH_BMIPS || ARCH_BCM68360 || \
+   depends on WDT && (ARCH_BMIPS || ARCH_BCM6750 || ARCH_BCM68360 || \
   ARCH_BCM6858 || ARCH_BCM63158)
help
  Select this to enable watchdog timer for BCM6345 SoCs.
-- 
2.7.4



[PATCH 2/6] gpio: do not include on ARCH_BCM6750

2020-03-06 Thread Philippe Reynes
As no gpio.h is defined for this architecture, to avoid
compilation failure, do not include  for
arch bcm6750.

Signed-off-by: Philippe Reynes 
---
 arch/arm/include/asm/gpio.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/include/asm/gpio.h b/arch/arm/include/asm/gpio.h
index 84e5cb4..cc178eb 100644
--- a/arch/arm/include/asm/gpio.h
+++ b/arch/arm/include/asm/gpio.h
@@ -5,7 +5,7 @@
!defined(CONFIG_ARCH_LS1028A) && !defined(CONFIG_ARCH_LS2080A) && \
!defined(CONFIG_ARCH_LS1088A) && !defined(CONFIG_ARCH_ASPEED) && \
!defined(CONFIG_ARCH_LS1012A) && !defined(CONFIG_ARCH_U8500) && \
-   !defined(CONFIG_CORTINA_PLATFORM)
+   !defined(CONFIG_CORTINA_PLATFORM) && !defined(CONFIG_ARCH_BCM6750)
 #include 
 #endif
 #include 
-- 
2.7.4



[PATCH 1/6] bcm6750: add initial support

2020-03-06 Thread Philippe Reynes
This add the initial support of the broadcom bcm6750 SoC family.

Signed-off-by: Philippe Reynes 
---
 arch/arm/Kconfig  |   7 ++
 arch/arm/dts/bcm6750.dtsi | 193 ++
 2 files changed, 200 insertions(+)
 create mode 100644 arch/arm/dts/bcm6750.dtsi

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 8d9f7fc..568b95a 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -633,6 +633,13 @@ config ARCH_BCM63158
select OF_CONTROL
imply CMD_DM
 
+config ARCH_BCM6750
+   bool "Broadcom BCM6750 family"
+   select CPU_V7A
+   select DM
+   select OF_CONTROL
+   imply CMD_DM
+
 config ARCH_BCM68360
bool "Broadcom BCM68360 family"
select DM
diff --git a/arch/arm/dts/bcm6750.dtsi b/arch/arm/dts/bcm6750.dtsi
new file mode 100644
index 000..108a8b3
--- /dev/null
+++ b/arch/arm/dts/bcm6750.dtsi
@@ -0,0 +1,193 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Philippe Reynes 
+ */
+
+#include "skeleton.dtsi"
+
+/ {
+   compatible = "brcm,bcm6750";
+   #address-cells = <1>;
+   #size-cells = <1>;
+
+   cpus {
+   #address-cells = <1>;
+   #size-cells = <0>;
+   u-boot,dm-pre-reloc;
+
+   cpu0: cpu@0 {
+   compatible = "arm,cortex-a7";
+   device_type = "cpu";
+   reg = <0x0>;
+   next-level-cache = <&l2>;
+   u-boot,dm-pre-reloc;
+   };
+
+   cpu1: cpu@1 {
+   compatible = "arm,cortex-a7";
+   device_type = "cpu";
+   reg = <0x1>;
+   next-level-cache = <&l2>;
+   u-boot,dm-pre-reloc;
+   };
+
+   cpu2: cpu@2 {
+   compatible = "arm,cortex-a7";
+   device_type = "cpu";
+   reg = <0x2>;
+   next-level-cache = <&l2>;
+   u-boot,dm-pre-reloc;
+   };
+
+   l2: l2-cache0 {
+   compatible = "cache";
+   u-boot,dm-pre-reloc;
+   };
+   };
+
+   clocks {
+   compatible = "simple-bus";
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges;
+   u-boot,dm-pre-reloc;
+
+   periph_osc: periph-osc {
+   compatible = "fixed-clock";
+   #clock-cells = <0>;
+   clock-frequency = <2>;
+   u-boot,dm-pre-reloc;
+   };
+
+   refclk50mhz: refclk50mhz {
+   compatible = "fixed-clock";
+   #clock-cells = <0>;
+   clock-frequency = <5000>;
+   };
+   };
+
+   ubus {
+   compatible = "simple-bus";
+   #address-cells = <1>;
+   #size-cells = <1>;
+   u-boot,dm-pre-reloc;
+
+   uart0: serial@ff812000 {
+   compatible = "arm,pl011", "arm,primecell";
+   reg = <0xff812000 0x1000>;
+   clock = <5000>;
+
+   status = "disabled";
+   };
+
+   wdt1: watchdog@ff800480 {
+   compatible = "brcm,bcm6345-wdt";
+   reg = <0xff800480 0x14>;
+   clocks = <&refclk50mhz>;
+   };
+
+   wdt2: watchdog@ff8004c0 {
+   compatible = "brcm,bcm6345-wdt";
+   reg = <0xff8004c0 0x14>;
+   clocks = <&refclk50mhz>;
+   };
+
+   wdt-reboot {
+   compatible = "wdt-reboot";
+   wdt = <&wdt1>;
+   };
+
+   gpio0: gpio-controller@0xff800500 {
+   compatible = "brcm,bcm6345-gpio";
+   reg = <0xff800500 0x4>,
+ <0xff800520 0x4>;
+   gpio-controller;
+   #gpio-cells = <2>;
+
+   status = "disabled";
+   };
+
+   gpio1: gpio-controller@0xff800504 {
+   compatible = "brcm,bcm6345-gpio";
+   reg = <0xff800504 0x4>,
+ <0xff800524 0x4&

[PATCH] tools: image-host.c: remove uboot_aes.h

2020-02-18 Thread Philippe Reynes
The include uboot_aes.h is not usefull and
it breaks the compilation on android, so
we remove it.

Signed-off-by: Philippe Reynes 
---
 tools/image-host.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/tools/image-host.c b/tools/image-host.c
index 9483561..76a361b 100644
--- a/tools/image-host.c
+++ b/tools/image-host.c
@@ -12,7 +12,6 @@
 #include 
 #include 
 #include 
-#include 
 
 /**
  * fit_set_hash_value - set hash value in requested has node
-- 
2.7.4



[PATCH] test: aes: fix memleak

2020-02-06 Thread Philippe Reynes
In the first version, the result of malloc is checked
with ut_assertnonnull. But on a fail, this macro exit
the function, so previously malloc are not freed.

So to avoid a memleak, we don't use ut_assertnonnull,
but simply check the return of malloc. If one has failed,
we freed all the allocated memory and quit the function.

Reported-by: Coverity (CID: 284403)
Reported-by: Coverity (CID: 284404)
Reported-by: Coverity (CID: 284405)
Reported-by: Coverity (CID: 284406)
Reported-by: Coverity (CID: 284407)
Signed-off-by: Philippe Reynes 
---
 test/lib/test_aes.c | 13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/test/lib/test_aes.c b/test/lib/test_aes.c
index b7b4b77..fb8a0b1 100644
--- a/test/lib/test_aes.c
+++ b/test/lib/test_aes.c
@@ -88,17 +88,17 @@ static int _lib_test_aes_run(struct unit_test_state *uts, 
int key_len,
 
/* Allocate all the buffer */
key = malloc(key_len);
-   ut_assertnonnull(key);
key_exp = malloc(key_exp_len);
-   ut_assertnonnull(key_exp);
iv = malloc(AES_BLOCK_LENGTH);
-   ut_assertnonnull(iv);
nocipher = malloc(num_block * AES_BLOCK_LENGTH);
-   ut_assertnonnull(nocipher);
ciphered = malloc((num_block + 1) * AES_BLOCK_LENGTH);
-   ut_assertnonnull(ciphered);
uncipher = malloc((num_block + 1) * AES_BLOCK_LENGTH);
-   ut_assertnonnull(uncipher);
+
+   if (!key || !key_exp || !iv || !nocipher || !ciphered || !uncipher) {
+   printf("%s: can't allocate memory\n", __func__);
+   ret = -1;
+   goto out;
+   }
 
/* Initialize all buffer */
rand_buf(key, key_len);
@@ -127,6 +127,7 @@ static int _lib_test_aes_run(struct unit_test_state *uts, 
int key_len,
ret = -1;
};
 
+ out:
/* Free all the data */
free(key);
free(key_exp);
-- 
2.7.4



Re: [PATCH V3 1/2] tpm: add a helper to iterate on all tpm devices

2020-01-09 Thread Philippe REYNES
Hi,

Sorry, I forgot to report the Reviewed-by of Miquel Raynal.


> Objet: [PATCH V3 1/2] tpm: add a helper to iterate on all tpm devices

> This add a helper for_each_tpm_device that run
> through all the tpm (1.x and 2.0) devices.
> 
> Signed-off-by: Philippe Reynes 

Reviewed-by: Miquel Raynal 

> ---
> include/tpm-common.h | 3 +++
> 1 file changed, 3 insertions(+)
> 
> Changelog:
> v3:
> - use the helper uclass_foreach_dev_probe
> v2:
> - new patch, add an helper for tpm device (idea from Miquel)
> 
> diff --git a/include/tpm-common.h b/include/tpm-common.h
> index f9c2ca2..702cd6e 100644
> --- a/include/tpm-common.h
> +++ b/include/tpm-common.h
> @@ -293,4 +293,7 @@ static inline cmd_tbl_t *get_tpm2_commands(unsigned int
> *size)
> */
> enum tpm_version tpm_get_version(struct udevice *dev);
> 
> +/* Iterate on all TPM devices */
> +#define for_each_tpm_device(dev) uclass_foreach_dev_probe(UCLASS_TPM, (dev))
> +
> #endif /* __TPM_COMMON_H */
> --
> 2.7.4

Regards,
Philippe


Re: [PATCH V3 2/2] cmd: tpm: add a subcommand device

2020-01-09 Thread Philippe REYNES
Hi,

Sorry, I forgot to report the Reviewed-by of Miquel Raynal.


> Objet: [PATCH V3 2/2] cmd: tpm: add a subcommand device

> The command tpm (and tpm2) search the tpm and use it.
> On sandbox, there are two tpm (tpm 1.x and tpm 2.0).
> So the command tpm and tpm2 are always executed with
> the first tpm (tpm 1.x), and the command tpm2 always
> fails.
> 
> This add a subcommand device to command tpm and
> command tpm2. Then the command tpm and tpm2 use
> the device selected with the subcommand device.
> 
> To be compatible with previous behaviour, if the
> subcommand device is not used before a tpm (or tpm2)
> command, the device 0 is selected.
> 
> Signed-off-by: Philippe Reynes 

Reviewed-by: Miquel Raynal 

> ---
> cmd/tpm-common.c | 77 +---
> cmd/tpm-user-utils.h | 1 +
> cmd/tpm-v1.c | 3 ++
> cmd/tpm-v2.c | 3 ++
> 4 files changed, 80 insertions(+), 4 deletions(-)
> 
> Changelog:
> v3:
> - no change
> v2:
> - use helper for tpm device (idea from Miquel)
> - don't set tpm in the look (feedback from Miquel)
> - add a comment to explain the backward code (feedback from Miquel)
> 
> diff --git a/cmd/tpm-common.c b/cmd/tpm-common.c
> index 38900fb..42882b1 100644
> --- a/cmd/tpm-common.c
> +++ b/cmd/tpm-common.c
> @@ -12,6 +12,8 @@
> #include 
> #include "tpm-user-utils.h"
> 
> +static struct udevice *tpm_dev;
> +
> /**
> * Print a byte string in hexdecimal format, 16-bytes per line.
> *
> @@ -231,19 +233,86 @@ int type_string_write_vars(const char *type_str, u8 
> *data,
> return 0;
> }
> 
> +static int tpm_show_device(void)
> +{
> + struct udevice *dev;
> + char buf[80];
> + int n = 0, rc;
> +
> + for_each_tpm_device(dev) {
> + rc = tpm_get_desc(dev, buf, sizeof(buf));
> + if (rc < 0)
> + printf("device %d: can't get info\n", n);
> + else
> + printf("device %d: %s\n", n, buf);
> +
> + n++;
> + };
> +
> + return 0;
> +}
> +
> +static int tpm_set_device(unsigned long num)
> +{
> + struct udevice *dev;
> + unsigned long n = 0;
> + int rc = CMD_RET_FAILURE;
> +
> + for_each_tpm_device(dev) {
> + if (n == num) {
> + rc = 0;
> + break;
> + }
> +
> + n++;
> + }
> +
> + if (!rc)
> + tpm_dev = dev;
> +
> + return rc;
> +}
> +
> int get_tpm(struct udevice **devp)
> {
> int rc;
> 
> - rc = uclass_first_device_err(UCLASS_TPM, devp);
> - if (rc) {
> - printf("Could not find TPM (ret=%d)\n", rc);
> - return CMD_RET_FAILURE;
> + /*
> + * To keep a backward compatibility with previous code,
> + * if a tpm device is not explicitly set, we set the first one.
> + */
> + if (!tpm_dev) {
> + rc = tpm_set_device(0);
> + if (rc) {
> + printf("Couldn't set TPM 0 (rc = %d)\n", rc);
> + return CMD_RET_FAILURE;
> + }
> }
> 
> + if (devp)
> + *devp = tpm_dev;
> +
> return 0;
> }
> 
> +int do_tpm_device(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
> +{
> + unsigned long num;
> + int rc;
> +
> + if (argc == 2) {
> + num = simple_strtoul(argv[1], NULL, 10);
> +
> + rc = tpm_set_device(num);
> + if (rc)
> + printf("Couldn't set TPM %lu (rc = %d)\n", num, rc);
> + } else {
> + rc = tpm_show_device();
> + }
> +
> + return rc;
> +}
> +
> int do_tpm_info(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
> {
> struct udevice *dev;
> diff --git a/cmd/tpm-user-utils.h b/cmd/tpm-user-utils.h
> index 8ce9861..a851d9c 100644
> --- a/cmd/tpm-user-utils.h
> +++ b/cmd/tpm-user-utils.h
> @@ -17,6 +17,7 @@ int type_string_pack(const char *type_str, char * const
> values[], u8 *data);
> int type_string_write_vars(const char *type_str, u8 *data, char * const 
> vars[]);
> int get_tpm(struct udevice **devp);
> 
> +int do_tpm_device(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]);
> int do_tpm_init(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]);
> int do_tpm_info(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]);
> int do_tpm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
> diff --git a/cmd/tpm-v1.c b/cmd/tpm-v1.c
> index 2807331..bc34e06 100644
> --- a/cmd/tpm-v1.c
> +++ b/cmd/tpm-v1.c
> @@ -645,6 +645,7 @@ TPM_COMMAND_NO_ARG(tpm_physical_enable)
> TPM_COMMAND_NO_ARG(tpm_physical_disable)
> 
> static cmd_tbl_t tpm1_commands[] = {
> + U_BOOT_CMD_MKENT(device, 0, 1, do_tpm_device, "", ""),
> U_BOOT_CMD_MKENT(info, 0, 1, do_tpm_info, "", ""),
> U_BOOT_CMD_MKENT(init, 0, 1, do_tpm_init, "", ""),
> U_BOOT_CMD_MKENT(startup, 

[PATCH V3 2/2] cmd: tpm: add a subcommand device

2020-01-09 Thread Philippe Reynes
The command tpm (and tpm2) search the tpm and use it.
On sandbox, there are two tpm (tpm 1.x and tpm 2.0).
So the command tpm and tpm2 are always executed with
the first tpm (tpm 1.x), and the command tpm2 always
fails.

This add a subcommand device to command tpm and
command tpm2. Then the command tpm and tpm2 use
the device selected with the subcommand device.

To be compatible with previous behaviour, if the
subcommand device is not used before a tpm (or tpm2)
command, the device 0 is selected.

Signed-off-by: Philippe Reynes 
---
 cmd/tpm-common.c | 77 +---
 cmd/tpm-user-utils.h |  1 +
 cmd/tpm-v1.c |  3 ++
 cmd/tpm-v2.c |  3 ++
 4 files changed, 80 insertions(+), 4 deletions(-)

Changelog:
v3:
- no change
v2:
- use helper for tpm device (idea from Miquel)
- don't set tpm in the look (feedback from Miquel)
- add a comment to explain the backward code (feedback from Miquel)

diff --git a/cmd/tpm-common.c b/cmd/tpm-common.c
index 38900fb..42882b1 100644
--- a/cmd/tpm-common.c
+++ b/cmd/tpm-common.c
@@ -12,6 +12,8 @@
 #include 
 #include "tpm-user-utils.h"
 
+static struct udevice *tpm_dev;
+
 /**
  * Print a byte string in hexdecimal format, 16-bytes per line.
  *
@@ -231,19 +233,86 @@ int type_string_write_vars(const char *type_str, u8 *data,
return 0;
 }
 
+static int tpm_show_device(void)
+{
+   struct udevice *dev;
+   char buf[80];
+   int n = 0, rc;
+
+   for_each_tpm_device(dev) {
+   rc = tpm_get_desc(dev, buf, sizeof(buf));
+   if (rc < 0)
+   printf("device %d: can't get info\n", n);
+   else
+   printf("device %d: %s\n", n, buf);
+
+   n++;
+   };
+
+   return 0;
+}
+
+static int tpm_set_device(unsigned long num)
+{
+   struct udevice *dev;
+   unsigned long n = 0;
+   int rc = CMD_RET_FAILURE;
+
+   for_each_tpm_device(dev) {
+   if (n == num) {
+   rc = 0;
+   break;
+   }
+
+   n++;
+   }
+
+   if (!rc)
+   tpm_dev = dev;
+
+   return rc;
+}
+
 int get_tpm(struct udevice **devp)
 {
int rc;
 
-   rc = uclass_first_device_err(UCLASS_TPM, devp);
-   if (rc) {
-   printf("Could not find TPM (ret=%d)\n", rc);
-   return CMD_RET_FAILURE;
+   /*
+* To keep a backward compatibility with previous code,
+* if a tpm device is not explicitly set, we set the first one.
+*/
+   if (!tpm_dev) {
+   rc = tpm_set_device(0);
+   if (rc) {
+   printf("Couldn't set TPM 0 (rc = %d)\n", rc);
+   return CMD_RET_FAILURE;
+   }
}
 
+   if (devp)
+   *devp = tpm_dev;
+
return 0;
 }
 
+int do_tpm_device(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+   unsigned long num;
+   int rc;
+
+   if (argc == 2) {
+   num = simple_strtoul(argv[1], NULL, 10);
+
+   rc = tpm_set_device(num);
+   if (rc)
+   printf("Couldn't set TPM %lu (rc = %d)\n", num, rc);
+   } else {
+   rc = tpm_show_device();
+   }
+
+   return rc;
+}
+
 int do_tpm_info(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 {
struct udevice *dev;
diff --git a/cmd/tpm-user-utils.h b/cmd/tpm-user-utils.h
index 8ce9861..a851d9c 100644
--- a/cmd/tpm-user-utils.h
+++ b/cmd/tpm-user-utils.h
@@ -17,6 +17,7 @@ int type_string_pack(const char *type_str, char * const 
values[], u8 *data);
 int type_string_write_vars(const char *type_str, u8 *data, char * const 
vars[]);
 int get_tpm(struct udevice **devp);
 
+int do_tpm_device(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]);
 int do_tpm_init(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]);
 int do_tpm_info(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]);
 int do_tpm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
diff --git a/cmd/tpm-v1.c b/cmd/tpm-v1.c
index 2807331..bc34e06 100644
--- a/cmd/tpm-v1.c
+++ b/cmd/tpm-v1.c
@@ -645,6 +645,7 @@ TPM_COMMAND_NO_ARG(tpm_physical_enable)
 TPM_COMMAND_NO_ARG(tpm_physical_disable)
 
 static cmd_tbl_t tpm1_commands[] = {
+   U_BOOT_CMD_MKENT(device, 0, 1, do_tpm_device, "", ""),
U_BOOT_CMD_MKENT(info, 0, 1, do_tpm_info, "", ""),
U_BOOT_CMD_MKENT(init, 0, 1, do_tpm_init, "", ""),
U_BOOT_CMD_MKENT(startup, 0, 1,
@@ -721,6 +722,8 @@ U_BOOT_CMD(tpm, CONFIG_SYS_MAXARGS, 1, do_tpm,
 "cmd args...\n"
 "- Issue TPM command  with arguments .\n"
 "Admin Startup and State Commands:\n"
+"  device [num device]\n"
+"- Show all devices o

[PATCH V3 1/2] tpm: add a helper to iterate on all tpm devices

2020-01-09 Thread Philippe Reynes
This add a helper for_each_tpm_device that run
through all the tpm (1.x and 2.0) devices.

Signed-off-by: Philippe Reynes 
---
 include/tpm-common.h | 3 +++
 1 file changed, 3 insertions(+)

Changelog:
v3:
- use the helper uclass_foreach_dev_probe
v2:
- new patch, add an helper for tpm device (idea from Miquel)

diff --git a/include/tpm-common.h b/include/tpm-common.h
index f9c2ca2..702cd6e 100644
--- a/include/tpm-common.h
+++ b/include/tpm-common.h
@@ -293,4 +293,7 @@ static inline cmd_tbl_t *get_tpm2_commands(unsigned int 
*size)
  */
 enum tpm_version tpm_get_version(struct udevice *dev);
 
+/* Iterate on all TPM devices */
+#define for_each_tpm_device(dev) uclass_foreach_dev_probe(UCLASS_TPM, (dev))
+
 #endif /* __TPM_COMMON_H */
-- 
2.7.4



[PATCH] test/cmd_ut.c: fix cmd_ut_category

2020-01-09 Thread Philippe Reynes
In the function cmd_ut_category, the prefix is used with
the function strncmp to know if the prefix should be
removed from the test name, even if the prefix is NULL.

To avoid this issue, we consider that a prefix NULL
mean no prefix. So we only try to remove the prefix
from the test_name if the prefix is not NULL, then
we avoid to call the function strncmp with a NULL
prefix.

Reported-by: Coverity CID 281110
Fixes: 4ad4edfe ("cmd_ut: add a parameter prefix to the function 
cmd_ut_category")
Signed-off-by: Philippe Reynes 
---
 test/cmd_ut.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test/cmd_ut.c b/test/cmd_ut.c
index 400719e..a3a9d49 100644
--- a/test/cmd_ut.c
+++ b/test/cmd_ut.c
@@ -26,7 +26,7 @@ int cmd_ut_category(const char *name, const char *prefix,
const char *test_name = test->name;
 
/* Remove the prefix */
-   if (!strncmp(test_name, prefix, prefix_len))
+   if (prefix && !strncmp(test_name, prefix, prefix_len))
test_name += prefix_len;
 
if (argc > 1 && strcmp(argv[1], test_name))
-- 
2.7.4



[PATCH V2 2/2] cmd: tpm: add a subcommand device

2020-01-09 Thread Philippe Reynes
The command tpm (and tpm2) search the tpm and use it.
On sandbox, there are two tpm (tpm 1.x and tpm 2.0).
So the command tpm and tpm2 are always executed with
the first tpm (tpm 1.x), and the command tpm2 always
fails.

This add a subcommand device to command tpm and
command tpm2. Then the command tpm and tpm2 use
the device selected with the subcommand device.

To be compatible with previous behaviour, if the
subcommand device is not used before a tpm (or tpm2)
command, the device 0 is selected.

Signed-off-by: Philippe Reynes 
---
 cmd/tpm-common.c | 77 +---
 cmd/tpm-user-utils.h |  1 +
 cmd/tpm-v1.c |  3 ++
 cmd/tpm-v2.c |  3 ++
 4 files changed, 80 insertions(+), 4 deletions(-)

Changelog:
v2:
- use helper for tpm device (idea from Miquel)
- don't set tpm in the look (feedback from Miquel)
- add a comment to explain the backward code (feedback from Miquel)

diff --git a/cmd/tpm-common.c b/cmd/tpm-common.c
index 38900fb..42882b1 100644
--- a/cmd/tpm-common.c
+++ b/cmd/tpm-common.c
@@ -12,6 +12,8 @@
 #include 
 #include "tpm-user-utils.h"
 
+static struct udevice *tpm_dev;
+
 /**
  * Print a byte string in hexdecimal format, 16-bytes per line.
  *
@@ -231,19 +233,86 @@ int type_string_write_vars(const char *type_str, u8 *data,
return 0;
 }
 
+static int tpm_show_device(void)
+{
+   struct udevice *dev;
+   char buf[80];
+   int n = 0, rc;
+
+   for_each_tpm_device(dev) {
+   rc = tpm_get_desc(dev, buf, sizeof(buf));
+   if (rc < 0)
+   printf("device %d: can't get info\n", n);
+   else
+   printf("device %d: %s\n", n, buf);
+
+   n++;
+   };
+
+   return 0;
+}
+
+static int tpm_set_device(unsigned long num)
+{
+   struct udevice *dev;
+   unsigned long n = 0;
+   int rc = CMD_RET_FAILURE;
+
+   for_each_tpm_device(dev) {
+   if (n == num) {
+   rc = 0;
+   break;
+   }
+
+   n++;
+   }
+
+   if (!rc)
+   tpm_dev = dev;
+
+   return rc;
+}
+
 int get_tpm(struct udevice **devp)
 {
int rc;
 
-   rc = uclass_first_device_err(UCLASS_TPM, devp);
-   if (rc) {
-   printf("Could not find TPM (ret=%d)\n", rc);
-   return CMD_RET_FAILURE;
+   /*
+* To keep a backward compatibility with previous code,
+* if a tpm device is not explicitly set, we set the first one.
+*/
+   if (!tpm_dev) {
+   rc = tpm_set_device(0);
+   if (rc) {
+   printf("Couldn't set TPM 0 (rc = %d)\n", rc);
+   return CMD_RET_FAILURE;
+   }
}
 
+   if (devp)
+   *devp = tpm_dev;
+
return 0;
 }
 
+int do_tpm_device(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+   unsigned long num;
+   int rc;
+
+   if (argc == 2) {
+   num = simple_strtoul(argv[1], NULL, 10);
+
+   rc = tpm_set_device(num);
+   if (rc)
+   printf("Couldn't set TPM %lu (rc = %d)\n", num, rc);
+   } else {
+   rc = tpm_show_device();
+   }
+
+   return rc;
+}
+
 int do_tpm_info(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 {
struct udevice *dev;
diff --git a/cmd/tpm-user-utils.h b/cmd/tpm-user-utils.h
index 8ce9861..a851d9c 100644
--- a/cmd/tpm-user-utils.h
+++ b/cmd/tpm-user-utils.h
@@ -17,6 +17,7 @@ int type_string_pack(const char *type_str, char * const 
values[], u8 *data);
 int type_string_write_vars(const char *type_str, u8 *data, char * const 
vars[]);
 int get_tpm(struct udevice **devp);
 
+int do_tpm_device(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]);
 int do_tpm_init(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]);
 int do_tpm_info(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]);
 int do_tpm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
diff --git a/cmd/tpm-v1.c b/cmd/tpm-v1.c
index 2807331..bc34e06 100644
--- a/cmd/tpm-v1.c
+++ b/cmd/tpm-v1.c
@@ -645,6 +645,7 @@ TPM_COMMAND_NO_ARG(tpm_physical_enable)
 TPM_COMMAND_NO_ARG(tpm_physical_disable)
 
 static cmd_tbl_t tpm1_commands[] = {
+   U_BOOT_CMD_MKENT(device, 0, 1, do_tpm_device, "", ""),
U_BOOT_CMD_MKENT(info, 0, 1, do_tpm_info, "", ""),
U_BOOT_CMD_MKENT(init, 0, 1, do_tpm_init, "", ""),
U_BOOT_CMD_MKENT(startup, 0, 1,
@@ -721,6 +722,8 @@ U_BOOT_CMD(tpm, CONFIG_SYS_MAXARGS, 1, do_tpm,
 "cmd args...\n"
 "- Issue TPM command  with arguments .\n"
 "Admin Startup and State Commands:\n"
+"  device [num device]\n"
+"- Show all devices or set the speci

[PATCH V2 1/2] tpm: add a helper to iterate on all tpm devices

2020-01-09 Thread Philippe Reynes
This add a helper for_each_tpm_device that run
through all the tpm (1.x and 2.0) devices.

Signed-off-by: Philippe Reynes 
---
 include/tpm-common.h | 6 ++
 1 file changed, 6 insertions(+)

Changelog:
v2:
- new patch, add an helper for tpm device (idea from Miquel)

diff --git a/include/tpm-common.h b/include/tpm-common.h
index f9c2ca2..5b33f47 100644
--- a/include/tpm-common.h
+++ b/include/tpm-common.h
@@ -293,4 +293,10 @@ static inline cmd_tbl_t *get_tpm2_commands(unsigned int 
*size)
  */
 enum tpm_version tpm_get_version(struct udevice *dev);
 
+/* Iterate on all TPM devices */
+#define for_each_tpm_device(dev)   \
+   for (uclass_first_device(UCLASS_TPM, &(dev));   \
+(dev); \
+uclass_next_device(&(dev)))
+
 #endif /* __TPM_COMMON_H */
-- 
2.7.4



[PATCH] cmd: tpm: add a subcommand device

2020-01-08 Thread Philippe Reynes
The command tpm (and tpm2) search the tpm and use it.
On sandbox, there are two tpm (tpm 1.x and tpm 2.0).
So the command tpm and tpm2 are always executed with
the first tpm (tpm 1.x), and the command tpm2 always
fails.

This add a subcommand device to command tpm and
command tpm2. Then the command tpm and tpm2 use
the device selected with the subcommand device.

To be compatible with previous behaviour, if the
subcommand device is not used before a tpm (or tpm2)
command, the device 0 is selected.

Signed-off-by: Philippe Reynes 
---
 cmd/tpm-common.c | 75 +---
 cmd/tpm-user-utils.h |  1 +
 cmd/tpm-v1.c |  3 +++
 cmd/tpm-v2.c |  3 +++
 4 files changed, 78 insertions(+), 4 deletions(-)

diff --git a/cmd/tpm-common.c b/cmd/tpm-common.c
index 38900fb..a99d438 100644
--- a/cmd/tpm-common.c
+++ b/cmd/tpm-common.c
@@ -12,6 +12,8 @@
 #include 
 #include "tpm-user-utils.h"
 
+static struct udevice *tpm_dev;
+
 /**
  * Print a byte string in hexdecimal format, 16-bytes per line.
  *
@@ -231,19 +233,84 @@ int type_string_write_vars(const char *type_str, u8 *data,
return 0;
 }
 
+static int tpm_show_device(void)
+{
+   struct udevice *dev;
+   char buf[80];
+   int n = 0, rc;
+
+   uclass_first_device(UCLASS_TPM, &dev);
+   while (dev) {
+   rc = tpm_get_desc(dev, buf, sizeof(buf));
+   if (rc < 0)
+   printf("device %d: can't get info\n", n);
+   else
+   printf("device %d: %s\n", n, buf);
+
+   uclass_next_device(&dev);
+   n++;
+   };
+
+   return 0;
+}
+
+static int tpm_set_device(unsigned long num)
+{
+   struct udevice *dev;
+   unsigned long n = 0;
+   int rc = CMD_RET_FAILURE;
+
+   uclass_first_device(UCLASS_TPM, &dev);
+   while (dev) {
+   if (n == num) {
+   tpm_dev = dev;
+   rc = 0;
+   break;
+   }
+
+   uclass_next_device(&dev);
+   n++;
+   };
+
+   return rc;
+}
+
 int get_tpm(struct udevice **devp)
 {
int rc;
 
-   rc = uclass_first_device_err(UCLASS_TPM, devp);
-   if (rc) {
-   printf("Could not find TPM (ret=%d)\n", rc);
-   return CMD_RET_FAILURE;
+   if (!tpm_dev) {
+   rc = tpm_set_device(0);
+   if (rc < 0) {
+   printf("Couldn't set TPM 0 (%d)\n", rc);
+   return CMD_RET_FAILURE;
+   }
}
 
+   if (devp)
+   *devp = tpm_dev;
+
return 0;
 }
 
+int do_tpm_device(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+   unsigned long num;
+   int rc;
+
+   if (argc == 2) {
+   num = simple_strtoul(argv[1], NULL, 10);
+
+   rc = tpm_set_device(num);
+   if (rc < 0)
+   printf("Couldn't set TPM %lu (%d)\n", num, rc);
+   } else {
+   rc = tpm_show_device();
+   }
+
+   return rc;
+}
+
 int do_tpm_info(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 {
struct udevice *dev;
diff --git a/cmd/tpm-user-utils.h b/cmd/tpm-user-utils.h
index 8ce9861..a851d9c 100644
--- a/cmd/tpm-user-utils.h
+++ b/cmd/tpm-user-utils.h
@@ -17,6 +17,7 @@ int type_string_pack(const char *type_str, char * const 
values[], u8 *data);
 int type_string_write_vars(const char *type_str, u8 *data, char * const 
vars[]);
 int get_tpm(struct udevice **devp);
 
+int do_tpm_device(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]);
 int do_tpm_init(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]);
 int do_tpm_info(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]);
 int do_tpm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
diff --git a/cmd/tpm-v1.c b/cmd/tpm-v1.c
index 2807331..bc34e06 100644
--- a/cmd/tpm-v1.c
+++ b/cmd/tpm-v1.c
@@ -645,6 +645,7 @@ TPM_COMMAND_NO_ARG(tpm_physical_enable)
 TPM_COMMAND_NO_ARG(tpm_physical_disable)
 
 static cmd_tbl_t tpm1_commands[] = {
+   U_BOOT_CMD_MKENT(device, 0, 1, do_tpm_device, "", ""),
U_BOOT_CMD_MKENT(info, 0, 1, do_tpm_info, "", ""),
U_BOOT_CMD_MKENT(init, 0, 1, do_tpm_init, "", ""),
U_BOOT_CMD_MKENT(startup, 0, 1,
@@ -721,6 +722,8 @@ U_BOOT_CMD(tpm, CONFIG_SYS_MAXARGS, 1, do_tpm,
 "cmd args...\n"
 "- Issue TPM command  with arguments .\n"
 "Admin Startup and State Commands:\n"
+"  device [num device]\n"
+"- Show all devices or set the specified device\n"
 "  info - Show information about the TPM\n"
 "  init\n"
 "- Put TPM into a state where it waits for 'startup&#x

[PATCH 8/8] bcm968360bg: add initial support

2020-01-07 Thread Philippe Reynes
This add the initial support of the broadcom reference
board bcm968360bg with a bcm68360 SoC.

This board has 512 MB of RAM, 256 MB of flash (nand),
2 USB port, 1 UART, and 4 ethernet ports.

Signed-off-by: Philippe Reynes 
---
 arch/arm/Kconfig |   1 +
 arch/arm/dts/Makefile|   3 +
 arch/arm/dts/bcm968360bg.dts | 168 +++
 board/broadcom/bcm968360bg/Kconfig   |  17 
 board/broadcom/bcm968360bg/MAINTAINERS   |   6 ++
 board/broadcom/bcm968360bg/Makefile  |   3 +
 board/broadcom/bcm968360bg/bcm968360bg.c |  61 +++
 configs/bcm968360bg_ram_defconfig|  53 ++
 include/configs/broadcom_bcm968360bg.h   |  40 
 9 files changed, 352 insertions(+)
 create mode 100644 arch/arm/dts/bcm968360bg.dts
 create mode 100644 board/broadcom/bcm968360bg/Kconfig
 create mode 100644 board/broadcom/bcm968360bg/MAINTAINERS
 create mode 100644 board/broadcom/bcm968360bg/Makefile
 create mode 100644 board/broadcom/bcm968360bg/bcm968360bg.c
 create mode 100644 configs/bcm968360bg_ram_defconfig
 create mode 100644 include/configs/broadcom_bcm968360bg.h

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 17f7454..60e0f6e 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1791,6 +1791,7 @@ source "board/armltd/vexpress64/Kconfig"
 source "board/broadcom/bcm23550_w1d/Kconfig"
 source "board/broadcom/bcm28155_ap/Kconfig"
 source "board/broadcom/bcm963158/Kconfig"
+source "board/broadcom/bcm968360bg/Kconfig"
 source "board/broadcom/bcm968580xref/Kconfig"
 source "board/broadcom/bcmcygnus/Kconfig"
 source "board/broadcom/bcmnsp/Kconfig"
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 0127a91..92d47e7 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -816,6 +816,9 @@ dtb-$(CONFIG_ARCH_BCM283X) += \
 dtb-$(CONFIG_ARCH_BCM63158) += \
bcm963158.dtb
 
+dtb-$(CONFIG_ARCH_BCM68360) += \
+   bcm968360bg.dtb
+
 dtb-$(CONFIG_ARCH_BCM6858) += \
bcm968580xref.dtb
 
diff --git a/arch/arm/dts/bcm968360bg.dts b/arch/arm/dts/bcm968360bg.dts
new file mode 100644
index 000..c060294
--- /dev/null
+++ b/arch/arm/dts/bcm968360bg.dts
@@ -0,0 +1,168 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 Philippe Reynes 
+ */
+
+/dts-v1/;
+
+#include "bcm68360.dtsi"
+
+/ {
+   model = "Broadcom bcm68360bg";
+   compatible = "broadcom,bcm68360bg", "brcm,bcm68360";
+
+   aliases {
+   serial0 = &uart0;
+   };
+
+   chosen {
+   stdout-path = "serial0:115200n8";
+   };
+
+   memory {
+   device_type = "memory";
+   reg = <0x0 0x0 0x0 0x2000>;
+   };
+};
+
+&uart0 {
+   u-boot,dm-pre-reloc;
+   status = "okay";
+};
+
+&gpio0 {
+   status = "okay";
+};
+
+&gpio1 {
+   status = "okay";
+};
+
+&gpio2 {
+   status = "okay";
+};
+
+&gpio3 {
+   status = "okay";
+};
+
+&gpio4 {
+   status = "okay";
+};
+
+&gpio5 {
+   status = "okay";
+};
+
+&gpio6 {
+   status = "okay";
+};
+
+&gpio7 {
+   status = "okay";
+};
+
+&nand {
+   status = "okay";
+   write-protect = <0>;
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   nandcs@0 {
+   compatible = "brcm,nandcs";
+   reg = <0>;
+   nand-ecc-strength = <4>;
+   nand-ecc-step-size = <512>;
+   brcm,nand-oob-sector-size = <16>;
+   };
+};
+
+&leds {
+   status = "okay";
+   #address-cells = <1>;
+   #size-cells = <0>;
+   brcm,serial-led-en-pol;
+   brcm,serial-led-data-ppol;
+
+   led@0 {
+   reg = <0>;
+   label = "red:alarm";
+   };
+
+   led@1 {
+   reg = <1>;
+   label = "green:wan";
+   };
+
+   led@2 {
+   reg = <2>;
+   label = "green:wps";
+   };
+
+   led@12 {
+   reg = <12>;
+   label = "orange:enet5.1";
+   };
+
+   led@13 {
+   reg = <13>;
+   label = "green:enet5.2";
+   };
+
+   led@14 {
+   reg = <14>;
+   label = "orange:enet5.2";
+   };
+
+   led@15 {
+   reg = <15>;
+   label = "green:enet5.1";
+   };
+
+   led@16 {
+   reg = <16>;
+   label = "green:usb1";
+   };
+
+   led@17 {
+   reg = <17>;
+   la

[PATCH 3/8] spi: bcm63xx-hsspi: allow to use this driver on arm bcm68360

2020-01-07 Thread Philippe Reynes
This IP is also used on some arm SoC, so we allow to
use it on arm bcm68360 too.

Signed-off-by: Philippe Reynes 
---
 drivers/spi/Kconfig | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index fae2040..73d1a69 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -84,7 +84,8 @@ config ATMEL_SPI
 
 config BCM63XX_HSSPI
bool "BCM63XX HSSPI driver"
-   depends on (ARCH_BMIPS || ARCH_BCM6858 || ARCH_BCM63158)
+   depends on (ARCH_BMIPS || ARCH_BCM68360 || \
+   ARCH_BCM6858 || ARCH_BCM63158)
help
  Enable the BCM6328 HSSPI driver. This driver can be used to
  access the SPI NOR flash on platforms embedding this Broadcom
-- 
2.7.4



[PATCH 5/8] led: bcm6858: allow to use this driver on arm bcm68360

2020-01-07 Thread Philippe Reynes
This IP is also used on some arm SoC, so we allow to
use it on arm bcm68360 too.

Signed-off-by: Philippe Reynes 
---
 drivers/led/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/led/Kconfig b/drivers/led/Kconfig
index 5643939..6675934 100644
--- a/drivers/led/Kconfig
+++ b/drivers/led/Kconfig
@@ -30,7 +30,7 @@ config LED_BCM6358
 
 config LED_BCM6858
bool "LED Support for BCM6858"
-   depends on LED && (ARCH_BCM6858 || ARCH_BCM63158)
+   depends on LED && (ARCH_BCM68360 || ARCH_BCM6858 || ARCH_BCM63158)
help
  This option enables support for LEDs connected to the BCM6858
  HW has blinking capabilities and up to 32 LEDs can be controlled.
-- 
2.7.4



[PATCH 6/8] gpio: bcm6345: allow to use this driver on arm bcm68360

2020-01-07 Thread Philippe Reynes
This IP is also used on some arm SoC, so we allow to
use it on arm bcm68360 too.

Signed-off-by: Philippe Reynes 
---
 drivers/gpio/Kconfig | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 1de6f52..4e5a707 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -55,7 +55,8 @@ config ALTERA_PIO
 
 config BCM6345_GPIO
bool "BCM6345 GPIO driver"
-   depends on DM_GPIO && (ARCH_BMIPS || ARCH_BCM6858 || ARCH_BCM63158)
+   depends on DM_GPIO && (ARCH_BMIPS || ARCH_BCM68360 || \
+  ARCH_BCM6858 || ARCH_BCM63158)
help
  This driver supports the GPIO banks on BCM6345 SoCs.
 
-- 
2.7.4



[PATCH 4/8] nand: brcmnand: add bcm68360 support

2020-01-07 Thread Philippe Reynes
This adds the nand support for chipset bcm68360.

Signed-off-by: Philippe Reynes 
---
 drivers/mtd/nand/raw/Kconfig  |   6 ++
 drivers/mtd/nand/raw/brcmnand/Makefile|   1 +
 drivers/mtd/nand/raw/brcmnand/bcm68360_nand.c | 123 ++
 3 files changed, 130 insertions(+)
 create mode 100644 drivers/mtd/nand/raw/brcmnand/bcm68360_nand.c

diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig
index 16165f8..158bb1b 100644
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
@@ -78,6 +78,12 @@ config NAND_BRCMNAND_6368
help
  Enable support for broadcom nand driver on bcm6368.
 
+config NAND_BRCMNAND_68360
+   bool "Support Broadcom NAND controller on bcm68360"
+   depends on NAND_BRCMNAND && ARCH_BCM68360
+   help
+ Enable support for broadcom nand driver on bcm68360.
+
 config NAND_BRCMNAND_6838
bool "Support Broadcom NAND controller on bcm6838"
depends on NAND_BRCMNAND && ARCH_BMIPS && SOC_BMIPS_BCM6838
diff --git a/drivers/mtd/nand/raw/brcmnand/Makefile 
b/drivers/mtd/nand/raw/brcmnand/Makefile
index 7e70b85..5d9e7e3 100644
--- a/drivers/mtd/nand/raw/brcmnand/Makefile
+++ b/drivers/mtd/nand/raw/brcmnand/Makefile
@@ -2,6 +2,7 @@
 
 obj-$(CONFIG_NAND_BRCMNAND_6368) += bcm6368_nand.o
 obj-$(CONFIG_NAND_BRCMNAND_63158) += bcm63158_nand.o
+obj-$(CONFIG_NAND_BRCMNAND_68360) += bcm68360_nand.o
 obj-$(CONFIG_NAND_BRCMNAND_6838) += bcm6838_nand.o
 obj-$(CONFIG_NAND_BRCMNAND_6858) += bcm6858_nand.o
 obj-$(CONFIG_NAND_BRCMNAND) += brcmnand.o
diff --git a/drivers/mtd/nand/raw/brcmnand/bcm68360_nand.c 
b/drivers/mtd/nand/raw/brcmnand/bcm68360_nand.c
new file mode 100644
index 000..0f1a28e
--- /dev/null
+++ b/drivers/mtd/nand/raw/brcmnand/bcm68360_nand.c
@@ -0,0 +1,123 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "brcmnand.h"
+
+struct bcm68360_nand_soc {
+   struct brcmnand_soc soc;
+   void __iomem *base;
+};
+
+#define BCM68360_NAND_INT  0x00
+#define BCM68360_NAND_STATUS_SHIFT 0
+#define BCM68360_NAND_STATUS_MASK  (0xfff << BCM68360_NAND_STATUS_SHIFT)
+
+#define BCM68360_NAND_INT_EN   0x04
+#define BCM68360_NAND_ENABLE_SHIFT 0
+#define BCM68360_NAND_ENABLE_MASK  (0x << BCM68360_NAND_ENABLE_SHIFT)
+
+enum {
+   BCM68360_NP_READ= BIT(0),
+   BCM68360_BLOCK_ERASE= BIT(1),
+   BCM68360_COPY_BACK  = BIT(2),
+   BCM68360_PAGE_PGM   = BIT(3),
+   BCM68360_CTRL_READY = BIT(4),
+   BCM68360_DEV_RBPIN  = BIT(5),
+   BCM68360_ECC_ERR_UNC= BIT(6),
+   BCM68360_ECC_ERR_CORR   = BIT(7),
+};
+
+static bool bcm68360_nand_intc_ack(struct brcmnand_soc *soc)
+{
+   struct bcm68360_nand_soc *priv =
+   container_of(soc, struct bcm68360_nand_soc, soc);
+   void __iomem *mmio = priv->base + BCM68360_NAND_INT;
+   u32 val = brcmnand_readl(mmio);
+
+   if (val & (BCM68360_CTRL_READY << BCM68360_NAND_STATUS_SHIFT)) {
+   /* Ack interrupt */
+   val &= ~BCM68360_NAND_STATUS_MASK;
+   val |= BCM68360_CTRL_READY << BCM68360_NAND_STATUS_SHIFT;
+   brcmnand_writel(val, mmio);
+   return true;
+   }
+
+   return false;
+}
+
+static void bcm68360_nand_intc_set(struct brcmnand_soc *soc, bool en)
+{
+   struct bcm68360_nand_soc *priv =
+   container_of(soc, struct bcm68360_nand_soc, soc);
+   void __iomem *mmio = priv->base + BCM68360_NAND_INT_EN;
+   u32 val = brcmnand_readl(mmio);
+
+   /* Don't ack any interrupts */
+   val &= ~BCM68360_NAND_STATUS_MASK;
+
+   if (en)
+   val |= BCM68360_CTRL_READY << BCM68360_NAND_ENABLE_SHIFT;
+   else
+   val &= ~(BCM68360_CTRL_READY << BCM68360_NAND_ENABLE_SHIFT);
+
+   brcmnand_writel(val, mmio);
+}
+
+static int bcm68360_nand_probe(struct udevice *dev)
+{
+   struct udevice *pdev = dev;
+   struct bcm68360_nand_soc *priv = dev_get_priv(dev);
+   struct brcmnand_soc *soc;
+   struct resource res;
+
+   soc = &priv->soc;
+
+   dev_read_resource_byname(pdev, "nand-int-base", &res);
+   priv->base = devm_ioremap(dev, res.start, resource_size(&res));
+   if (IS_ERR(priv->base))
+   return PTR_ERR(priv->base);
+
+   soc->ctlrdy_ack = bcm68360_nand_intc_ack;
+   soc->ctlrdy_set_enabled = bcm68360_nand_intc_set;
+
+   /* Disable and ack all interrupts  */
+   brcmnand_writel(0, priv->base + BCM68360_NAND_INT_EN);
+   brcmnand_writel(0, priv->base + BCM68360_NAND_INT);
+
+   return brcmnand_probe(pdev, soc);
+}
+
+static const struct udevice_id bcm68360_nand_dt_

[PATCH 7/8] gpio: do not include on ARCH_BCM68360

2020-01-07 Thread Philippe Reynes
As no gpio.h is defined for this architecture, to avoid
compilation failure, do not include  for
arch bcm68360.

Signed-off-by: Philippe Reynes 
---
 arch/arm/include/asm/gpio.h | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/arm/include/asm/gpio.h b/arch/arm/include/asm/gpio.h
index 6ff5f42..5b4dee0 100644
--- a/arch/arm/include/asm/gpio.h
+++ b/arch/arm/include/asm/gpio.h
@@ -1,9 +1,9 @@
 #if !defined(CONFIG_ARCH_UNIPHIER) && !defined(CONFIG_ARCH_STI) && \
-   !defined(CONFIG_ARCH_K3) && !defined(CONFIG_ARCH_BCM6858) && \
-   !defined(CONFIG_ARCH_BCM63158) && !defined(CONFIG_ARCH_ROCKCHIP) && \
-   !defined(CONFIG_ARCH_LX2160A) && !defined(CONFIG_ARCH_LS1028A) && \
-   !defined(CONFIG_ARCH_LS2080A) && !defined(CONFIG_ARCH_LS1088A) && \
-   !defined(CONFIG_ARCH_ASPEED)
+   !defined(CONFIG_ARCH_K3) && !defined(CONFIG_ARCH_BCM68360) && \
+   !defined(CONFIG_ARCH_BCM6858) && !defined(CONFIG_ARCH_BCM63158) && \
+   !defined(CONFIG_ARCH_ROCKCHIP) && !defined(CONFIG_ARCH_LX2160A) && \
+   !defined(CONFIG_ARCH_LS1028A) && !defined(CONFIG_ARCH_LS2080A) && \
+   !defined(CONFIG_ARCH_LS1088A) && !defined(CONFIG_ARCH_ASPEED)
 #include 
 #endif
 #include 
-- 
2.7.4



[PATCH 2/8] watchdog: bcm6345: allow to use this driver on arm bcm68360

2020-01-07 Thread Philippe Reynes
This IP is also used on some arm SoC, so we allow to
use it on arm bcm68360 too.

Signed-off-by: Philippe Reynes 
---
 drivers/watchdog/Kconfig | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 8c16d69..2b8064d 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -85,7 +85,8 @@ config WDT_AT91
 
 config WDT_BCM6345
bool "BCM6345 watchdog timer support"
-   depends on WDT && (ARCH_BMIPS || ARCH_BCM6858 || ARCH_BCM63158)
+   depends on WDT && (ARCH_BMIPS || ARCH_BCM68360 || \
+  ARCH_BCM6858 || ARCH_BCM63158)
help
  Select this to enable watchdog timer for BCM6345 SoCs.
  The watchdog timer is stopped when initialized.
-- 
2.7.4



[PATCH 1/8] bcm68360: add initial support

2020-01-07 Thread Philippe Reynes
This add the initial support of the broadcom bcm68360 SoC family.

Signed-off-by: Philippe Reynes 
---
 arch/arm/Kconfig   |   6 ++
 arch/arm/dts/bcm68360.dtsi | 217 +
 2 files changed, 223 insertions(+)
 create mode 100644 arch/arm/dts/bcm68360.dtsi

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 36c9c2f..17f7454 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -622,6 +622,12 @@ config ARCH_BCM63158
select OF_CONTROL
imply CMD_DM
 
+config ARCH_BCM68360
+   bool "Broadcom BCM68360 family"
+   select DM
+   select OF_CONTROL
+   imply CMD_DM
+
 config ARCH_BCM6858
bool "Broadcom BCM6858 family"
select DM
diff --git a/arch/arm/dts/bcm68360.dtsi b/arch/arm/dts/bcm68360.dtsi
new file mode 100644
index 000..7bbe207
--- /dev/null
+++ b/arch/arm/dts/bcm68360.dtsi
@@ -0,0 +1,217 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 Philippe Reynes 
+ */
+
+#include "skeleton64.dtsi"
+
+/ {
+   compatible = "brcm,bcm68360";
+   #address-cells = <2>;
+   #size-cells = <2>;
+
+   aliases {
+   spi0 = &hsspi;
+   };
+
+   cpus {
+   #address-cells = <2>;
+   #size-cells = <0>;
+   u-boot,dm-pre-reloc;
+
+   cpu0: cpu@0 {
+   compatible = "arm,cortex-a53", "arm,armv8";
+   device_type = "cpu";
+   reg = <0x0 0x0>;
+   next-level-cache = <&l2>;
+   u-boot,dm-pre-reloc;
+   };
+
+   cpu1: cpu@1 {
+   compatible = "arm,cortex-a53", "arm,armv8";
+   device_type = "cpu";
+   reg = <0x0 0x1>;
+   next-level-cache = <&l2>;
+   u-boot,dm-pre-reloc;
+   };
+
+   l2: l2-cache0 {
+   compatible = "cache";
+   u-boot,dm-pre-reloc;
+   };
+   };
+
+   clocks {
+   compatible = "simple-bus";
+   #address-cells = <2>;
+   #size-cells = <2>;
+   ranges;
+   u-boot,dm-pre-reloc;
+
+   periph_osc: periph-osc {
+   compatible = "fixed-clock";
+   #clock-cells = <0>;
+   clock-frequency = <2>;
+   u-boot,dm-pre-reloc;
+   };
+
+   hsspi_pll: hsspi-pll {
+   compatible = "fixed-factor-clock";
+   #clock-cells = <0>;
+   clocks = <&periph_osc>;
+   clock-mult = <2>;
+   clock-div = <1>;
+   };
+
+   refclk50mhz: refclk50mhz {
+   compatible = "fixed-clock";
+   #clock-cells = <0>;
+   clock-frequency = <5000>;
+   };
+   };
+
+   ubus {
+   compatible = "simple-bus";
+   #address-cells = <2>;
+   #size-cells = <2>;
+   u-boot,dm-pre-reloc;
+
+   wdt1: watchdog@ff800480 {
+   compatible = "brcm,bcm6345-wdt";
+   reg = <0x0 0xff800480 0x0 0x14>;
+   clocks = <&refclk50mhz>;
+   };
+
+   wdt2: watchdog@ff8004c0 {
+   compatible = "brcm,bcm6345-wdt";
+   reg = <0x0 0xff8004c0 0x0 0x14>;
+   clocks = <&refclk50mhz>;
+   };
+
+   wdt-reboot {
+   compatible = "wdt-reboot";
+   wdt = <&wdt1>;
+   };
+
+   uart0: serial@ff800640 {
+   compatible = "brcm,bcm6345-uart";
+   reg = <0x0 0xff800640 0x0 0x18>;
+   clocks = <&periph_osc>;
+
+   status = "disabled";
+   };
+
+   leds: led-controller@ff800800 {
+   compatible = "brcm,bcm6858-leds";
+   reg = <0x0 0xff800800 0x0 0xe4>;
+
+   status = "disabled";
+   };
+
+   gpio0: gpio-controller@0xff800500 {
+   compatible = "brcm,bcm6345-gpio";
+   reg = <0x0 0xff800500 0x0 0x4>,
+ <0x0 0xff800520 0x0 0x4>;
+  

[PATCH V4 4/4] aes: add test unit for aes196 and aes256

2020-01-06 Thread Philippe Reynes
This commit add test unit for aes196 and aes256.

Signed-off-by: Philippe Reynes 
---
 test/lib/test_aes.c | 4 
 1 file changed, 4 insertions(+)

Changelog:
v4:
- no change
v3:
- new patch in this serie (in the previous version, the test to
  aes was added to pytest, now, we add test unit for aes as proposed by Simon)

diff --git a/test/lib/test_aes.c b/test/lib/test_aes.c
index 2b0e894..b7b4b77 100644
--- a/test/lib/test_aes.c
+++ b/test/lib/test_aes.c
@@ -26,6 +26,10 @@ struct test_aes_s {
 static struct test_aes_s test_aes[] = {
{ AES128_KEY_LENGTH, AES128_EXPAND_KEY_LENGTH, TEST_AES_ONE_BLOCK,  1 },
{ AES128_KEY_LENGTH, AES128_EXPAND_KEY_LENGTH, TEST_AES_CBC_CHAIN, 16 },
+   { AES192_KEY_LENGTH, AES192_EXPAND_KEY_LENGTH, TEST_AES_ONE_BLOCK,  1 },
+   { AES192_KEY_LENGTH, AES192_EXPAND_KEY_LENGTH, TEST_AES_CBC_CHAIN, 16 },
+   { AES256_KEY_LENGTH, AES256_EXPAND_KEY_LENGTH, TEST_AES_ONE_BLOCK,  1 },
+   { AES256_KEY_LENGTH, AES256_EXPAND_KEY_LENGTH, TEST_AES_CBC_CHAIN, 16 },
 };
 
 static void rand_buf(u8 *buf, int size)
-- 
2.7.4



[PATCH V4 2/4] aes: add support of aes192 and aes256

2020-01-06 Thread Philippe Reynes
Until now, we only support aes128. This commit add the support
of aes192 and aes256.

Signed-off-by: Philippe Reynes 
---
 arch/arm/mach-tegra/tegra20/crypto.c | 41 ++-
 cmd/aes.c| 38 --
 include/uboot_aes.h  | 34 ++--
 lib/aes.c| 77 +---
 4 files changed, 125 insertions(+), 65 deletions(-)

Changelog:
v4:
- update the tge driver crypto for tegra20 to use the new aes api.
  (squash previous patch 3, feedback from Simon)
v3:
- no change
v2:
- fix the help for the aes command


diff --git a/arch/arm/mach-tegra/tegra20/crypto.c 
b/arch/arm/mach-tegra/tegra20/crypto.c
index 66fbc3b..b91191e 100644
--- a/arch/arm/mach-tegra/tegra20/crypto.c
+++ b/arch/arm/mach-tegra/tegra20/crypto.c
@@ -39,34 +39,35 @@ static void left_shift_vector(u8 *in, u8 *out, int size)
 /**
  * Sign a block of data, putting the result into dst.
  *
- * \param key  Input AES key, length AES_KEY_LENGTH
+ * \param key  Input AES key, length AES128_KEY_LENGTH
  * \param key_schedule Expanded key to use
  * \param src  Source data of length 'num_aes_blocks' blocks
- * \param dst  Destination buffer, length AES_KEY_LENGTH
+ * \param dst  Destination buffer, length AES128_KEY_LENGTH
  * \param num_aes_blocks   Number of AES blocks to encrypt
  */
 static void sign_object(u8 *key, u8 *key_schedule, u8 *src, u8 *dst,
u32 num_aes_blocks)
 {
-   u8 tmp_data[AES_KEY_LENGTH];
-   u8 iv[AES_KEY_LENGTH] = {0};
-   u8 left[AES_KEY_LENGTH];
-   u8 k1[AES_KEY_LENGTH];
+   u8 tmp_data[AES128_KEY_LENGTH];
+   u8 iv[AES128_KEY_LENGTH] = {0};
+   u8 left[AES128_KEY_LENGTH];
+   u8 k1[AES128_KEY_LENGTH];
u8 *cbc_chain_data;
unsigned i;
 
cbc_chain_data = zero_key;  /* Convenient array of 0's for IV */
 
/* compute K1 constant needed by AES-CMAC calculation */
-   for (i = 0; i < AES_KEY_LENGTH; i++)
+   for (i = 0; i < AES128_KEY_LENGTH; i++)
tmp_data[i] = 0;
 
-   aes_cbc_encrypt_blocks(key_schedule, iv, tmp_data, left, 1);
+   aes_cbc_encrypt_blocks(AES128_KEY_LENGTH, key_schedule, iv,
+  tmp_data, left, 1);
 
left_shift_vector(left, k1, sizeof(left));
 
if ((left[0] >> 7) != 0) /* get MSB of L */
-   k1[AES_KEY_LENGTH-1] ^= AES_CMAC_CONST_RB;
+   k1[AES128_KEY_LENGTH - 1] ^= AES_CMAC_CONST_RB;
 
/* compute the AES-CMAC value */
for (i = 0; i < num_aes_blocks; i++) {
@@ -78,31 +79,32 @@ static void sign_object(u8 *key, u8 *key_schedule, u8 *src, 
u8 *dst,
aes_apply_cbc_chain_data(tmp_data, k1, tmp_data);
 
/* encrypt the AES block */
-   aes_encrypt(tmp_data, key_schedule, dst);
+   aes_encrypt(AES128_KEY_LENGTH, tmp_data,
+   key_schedule, dst);
 
debug("sign_obj: block %d of %d\n", i, num_aes_blocks);
 
/* Update pointers for next loop. */
cbc_chain_data = dst;
-   src += AES_KEY_LENGTH;
+   src += AES128_KEY_LENGTH;
}
 }
 
 /**
  * Encrypt and sign a block of data (depending on security mode).
  *
- * \param key  Input AES key, length AES_KEY_LENGTH
+ * \param key  Input AES key, length AES128_KEY_LENGTH
  * \param oper Security operations mask to perform (enum security_op)
  * \param src  Source data
  * \param length   Size of source data
- * \param sig_dst  Destination address for signature, AES_KEY_LENGTH bytes
+ * \param sig_dst  Destination address for signature, AES128_KEY_LENGTH 
bytes
  */
 static int encrypt_and_sign(u8 *key, enum security_op oper, u8 *src,
u32 length, u8 *sig_dst)
 {
u32 num_aes_blocks;
-   u8 key_schedule[AES_EXPAND_KEY_LENGTH];
-   u8 iv[AES_KEY_LENGTH] = {0};
+   u8 key_schedule[AES128_EXPAND_KEY_LENGTH];
+   u8 iv[AES128_KEY_LENGTH] = {0};
 
debug("encrypt_and_sign: length = %d\n", length);
 
@@ -110,15 +112,16 @@ static int encrypt_and_sign(u8 *key, enum security_op 
oper, u8 *src,
 * The only need for a key is for signing/checksum purposes, so
 * if not encrypting, expand a key of 0s.
 */
-   aes_expand_key(oper & SECURITY_ENCRYPT ? key : zero_key, key_schedule);
+   aes_expand_key(oper & SECURITY_ENCRYPT ? key : zero_key,
+  AES128_KEY_LENGTH, key_schedule);
 
-   num_aes_blocks = (length + AES_KEY_LENGTH - 1) / AES_KEY_LENGTH;
+   num_aes_blocks = (length + AES128_KEY_LENGTH - 1) / AES128_KEY_LENGTH;
 
if (oper & SECURITY_ENCRYPT) {
/* Perform this in pla

[PATCH V4 3/4] aes: add test unit for aes128

2020-01-06 Thread Philippe Reynes
This commit add test unit for aes128.

Signed-off-by: Philippe Reynes 
---
 test/lib/Makefile   |   1 +
 test/lib/test_aes.c | 162 
 2 files changed, 163 insertions(+)
 create mode 100644 test/lib/test_aes.c

Changelog:
v4:
- Put test/ headers at the end (feedback from Simon)
v3:
- new patch in this serie (in the previous version, the test to
  aes was added to pytest, now, we add test unit for aes as proposed by Simon)

diff --git a/test/lib/Makefile b/test/lib/Makefile
index 72d2ec7..230068d 100644
--- a/test/lib/Makefile
+++ b/test/lib/Makefile
@@ -8,3 +8,4 @@ obj-y += lmb.o
 obj-y += string.o
 obj-$(CONFIG_ERRNO_STR) += test_errno_str.o
 obj-$(CONFIG_UT_LIB_ASN1) += asn1.o
+obj-$(CONFIG_AES) += test_aes.o
diff --git a/test/lib/test_aes.c b/test/lib/test_aes.c
new file mode 100644
index 000..2b0e894
--- /dev/null
+++ b/test/lib/test_aes.c
@@ -0,0 +1,162 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2019 Philippe Reynes 
+ *
+ * Unit tests for aes functions
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define TEST_AES_ONE_BLOCK 0
+#define TEST_AES_CBC_CHAIN 1
+
+struct test_aes_s {
+   int key_len;
+   int key_exp_len;
+   int type;
+   int num_block;
+};
+
+static struct test_aes_s test_aes[] = {
+   { AES128_KEY_LENGTH, AES128_EXPAND_KEY_LENGTH, TEST_AES_ONE_BLOCK,  1 },
+   { AES128_KEY_LENGTH, AES128_EXPAND_KEY_LENGTH, TEST_AES_CBC_CHAIN, 16 },
+};
+
+static void rand_buf(u8 *buf, int size)
+{
+   int i;
+
+   for (i = 0; i < size; i++)
+   buf[i] = rand() & 0xff;
+}
+
+static int lib_test_aes_one_block(struct unit_test_state *uts, int key_len,
+ u8 *key_exp, u8 *iv, int num_block,
+ u8 *nocipher, u8 *ciphered, u8 *uncipher)
+{
+   aes_encrypt(key_len, nocipher, key_exp, ciphered);
+   aes_decrypt(key_len, ciphered, key_exp, uncipher);
+
+   ut_asserteq_mem(nocipher, uncipher, AES_BLOCK_LENGTH);
+
+   /* corrupt the expanded key */
+   key_exp[0]++;
+   aes_decrypt(key_len, ciphered, key_exp, uncipher);
+   ut_assertf(memcmp(nocipher, uncipher, AES_BLOCK_LENGTH),
+  "nocipher and uncipher should be different\n");
+
+   return 0;
+}
+
+static int lib_test_aes_cbc_chain(struct unit_test_state *uts, int key_len,
+ u8 *key_exp, u8 *iv, int num_block,
+ u8 *nocipher, u8 *ciphered, u8 *uncipher)
+{
+   aes_cbc_encrypt_blocks(key_len, key_exp, iv,
+  nocipher, ciphered, num_block);
+   aes_cbc_decrypt_blocks(key_len, key_exp, iv,
+  ciphered, uncipher, num_block);
+
+   ut_asserteq_mem(nocipher, uncipher, num_block * AES_BLOCK_LENGTH);
+
+   /* corrupt the expanded key */
+   key_exp[0]++;
+   aes_cbc_decrypt_blocks(key_len, key_exp, iv,
+  ciphered, uncipher, num_block);
+   ut_assertf(memcmp(nocipher, uncipher, num_block * AES_BLOCK_LENGTH),
+  "nocipher and uncipher should be different\n");
+
+   return 0;
+}
+
+static int _lib_test_aes_run(struct unit_test_state *uts, int key_len,
+int key_exp_len, int type, int num_block)
+{
+   u8 *key, *key_exp, *iv;
+   u8 *nocipher, *ciphered, *uncipher;
+   int ret;
+
+   /* Allocate all the buffer */
+   key = malloc(key_len);
+   ut_assertnonnull(key);
+   key_exp = malloc(key_exp_len);
+   ut_assertnonnull(key_exp);
+   iv = malloc(AES_BLOCK_LENGTH);
+   ut_assertnonnull(iv);
+   nocipher = malloc(num_block * AES_BLOCK_LENGTH);
+   ut_assertnonnull(nocipher);
+   ciphered = malloc((num_block + 1) * AES_BLOCK_LENGTH);
+   ut_assertnonnull(ciphered);
+   uncipher = malloc((num_block + 1) * AES_BLOCK_LENGTH);
+   ut_assertnonnull(uncipher);
+
+   /* Initialize all buffer */
+   rand_buf(key, key_len);
+   rand_buf(iv, AES_BLOCK_LENGTH);
+   rand_buf(nocipher, num_block * AES_BLOCK_LENGTH);
+   memset(ciphered, 0, (num_block + 1) * AES_BLOCK_LENGTH);
+   memset(uncipher, 0, (num_block + 1) * AES_BLOCK_LENGTH);
+
+   /* Expand the key */
+   aes_expand_key(key, key_len, key_exp);
+
+   /* Encrypt and decrypt */
+   switch (type) {
+   case TEST_AES_ONE_BLOCK:
+   ret = lib_test_aes_one_block(uts, key_len, key_exp, iv,
+num_block, nocipher,
+ciphered, uncipher);
+   break;
+   case TEST_AES_CBC_CHAIN:
+   ret = lib_test_aes_cbc_chain(uts, key_len, key_exp, iv,
+num_block, nocipher,
+ciphered, uncip

[PATCH V4 1/4] aes: add a define for the size of a block

2020-01-06 Thread Philippe Reynes
In the code, we use the size of the key for the
size of the block. It's true when the key is 128 bits,
but it become false for key of 192 bits and 256 bits.
So to prepare the support of aes192  and 256,
we introduce a constant for the iaes block size.

Signed-off-by: Philippe Reynes 
---
 cmd/aes.c   |  2 +-
 include/uboot_aes.h |  5 +++--
 lib/aes.c   | 34 +-
 3 files changed, 21 insertions(+), 20 deletions(-)

Changelog:
v4:
- no change
v3:
- no change
v2:
- no change

diff --git a/cmd/aes.c b/cmd/aes.c
index 8c61cee..24b0256 100644
--- a/cmd/aes.c
+++ b/cmd/aes.c
@@ -56,7 +56,7 @@ static int do_aes(cmd_tbl_t *cmdtp, int flag, int argc, char 
*const argv[])
aes_expand_key(key_ptr, key_exp);
 
/* Calculate the number of AES blocks to encrypt. */
-   aes_blocks = DIV_ROUND_UP(len, AES_KEY_LENGTH);
+   aes_blocks = DIV_ROUND_UP(len, AES_BLOCK_LENGTH);
 
if (enc)
aes_cbc_encrypt_blocks(key_exp, iv_ptr, src_ptr, dst_ptr,
diff --git a/include/uboot_aes.h b/include/uboot_aes.h
index 2fda384..1ae3ac9 100644
--- a/include/uboot_aes.h
+++ b/include/uboot_aes.h
@@ -18,7 +18,7 @@ typedef unsigned int u32;
  * AES encryption library, with small code size, supporting only 128-bit AES
  *
  * AES is a stream cipher which works a block at a time, with each block
- * in this case being AES_KEY_LENGTH bytes.
+ * in this case being AES_BLOCK_LENGTH bytes.
  */
 
 enum {
@@ -28,6 +28,7 @@ enum {
 
AES_KEY_LENGTH  = 128 / 8,
AES_EXPAND_KEY_LENGTH   = 4 * AES_STATECOLS * (AES_ROUNDS + 1),
+   AES_BLOCK_LENGTH= 128 / 8,
 };
 
 /**
@@ -62,7 +63,7 @@ void aes_decrypt(u8 *in, u8 *expkey, u8 *out);
 /**
  * Apply chain data to the destination using EOR
  *
- * Each array is of length AES_KEY_LENGTH.
+ * Each array is of length AES_BLOCK_LENGTH.
  *
  * @cbc_chain_data Chain data
  * @srcSource data
diff --git a/lib/aes.c b/lib/aes.c
index a12a192..cfa57b6 100644
--- a/lib/aes.c
+++ b/lib/aes.c
@@ -596,62 +596,62 @@ void aes_apply_cbc_chain_data(u8 *cbc_chain_data, u8 
*src, u8 *dst)
 {
int i;
 
-   for (i = 0; i < AES_KEY_LENGTH; i++)
+   for (i = 0; i < AES_BLOCK_LENGTH; i++)
*dst++ = *src++ ^ *cbc_chain_data++;
 }
 
 void aes_cbc_encrypt_blocks(u8 *key_exp, u8 *iv, u8 *src, u8 *dst,
u32 num_aes_blocks)
 {
-   u8 tmp_data[AES_KEY_LENGTH];
+   u8 tmp_data[AES_BLOCK_LENGTH];
u8 *cbc_chain_data = iv;
u32 i;
 
for (i = 0; i < num_aes_blocks; i++) {
debug("encrypt_object: block %d of %d\n", i, num_aes_blocks);
-   debug_print_vector("AES Src", AES_KEY_LENGTH, src);
+   debug_print_vector("AES Src", AES_BLOCK_LENGTH, src);
 
/* Apply the chain data */
aes_apply_cbc_chain_data(cbc_chain_data, src, tmp_data);
-   debug_print_vector("AES Xor", AES_KEY_LENGTH, tmp_data);
+   debug_print_vector("AES Xor", AES_BLOCK_LENGTH, tmp_data);
 
/* Encrypt the AES block */
aes_encrypt(tmp_data, key_exp, dst);
-   debug_print_vector("AES Dst", AES_KEY_LENGTH, dst);
+   debug_print_vector("AES Dst", AES_BLOCK_LENGTH, dst);
 
/* Update pointers for next loop. */
cbc_chain_data = dst;
-   src += AES_KEY_LENGTH;
-   dst += AES_KEY_LENGTH;
+   src += AES_BLOCK_LENGTH;
+   dst += AES_BLOCK_LENGTH;
}
 }
 
 void aes_cbc_decrypt_blocks(u8 *key_exp, u8 *iv, u8 *src, u8 *dst,
u32 num_aes_blocks)
 {
-   u8 tmp_data[AES_KEY_LENGTH], tmp_block[AES_KEY_LENGTH];
+   u8 tmp_data[AES_BLOCK_LENGTH], tmp_block[AES_BLOCK_LENGTH];
/* Convenient array of 0's for IV */
-   u8 cbc_chain_data[AES_KEY_LENGTH];
+   u8 cbc_chain_data[AES_BLOCK_LENGTH];
u32 i;
 
-   memcpy(cbc_chain_data, iv, AES_KEY_LENGTH);
+   memcpy(cbc_chain_data, iv, AES_BLOCK_LENGTH);
for (i = 0; i < num_aes_blocks; i++) {
debug("encrypt_object: block %d of %d\n", i, num_aes_blocks);
-   debug_print_vector("AES Src", AES_KEY_LENGTH, src);
+   debug_print_vector("AES Src", AES_BLOCK_LENGTH, src);
 
-   memcpy(tmp_block, src, AES_KEY_LENGTH);
+   memcpy(tmp_block, src, AES_BLOCK_LENGTH);
 
/* Decrypt the AES block */
aes_decrypt(src, key_exp, tmp_data);
-   debug_print_vector("AES Xor", AES_KEY_LENGTH, tmp_data);
+   debug_print_vector("AES Xor", AES_BLOCK_LENGTH, tmp_data);
 
/* Apply the chain data */
aes_apply_cbc_chain_data(cbc_chain_data, tmp_data,

<    1   2   3   4   5   6   >