summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaisuke Nojiri <dnojiri@chromium.org>2017-07-07 09:49:36 -0700
committerchrome-bot <chrome-bot@chromium.org>2017-07-13 19:45:57 -0700
commit4ec4975d90713b58557beca7ed2a94745d7476e3 (patch)
treeb6f5cf7601f271944de4793cfd2392b5954659e5
parent7630636a0fe8ceb2dbba2b175564a17900d175cf (diff)
downloadchrome-ec-4ec4975d90713b58557beca7ed2a94745d7476e3.tar.gz
vboot: Move common code under common/vboot
This patch moves the code which can be shared with other data verification schemes (e.g. RWSIG) under common/vboot. It also adds unit tests for it. BUG=b:38462249 BRANCH=none TEST=make run-vboot. Verify verification succeeds on Fizz. Change-Id: Icab4d96dd2c154a12b01c41ebe9b46286b4b590e Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/563463 Reviewed-by: Randall Spangler <rspangler@chromium.org>
-rw-r--r--Makefile1
-rw-r--r--common/build.mk5
-rw-r--r--common/vboot/common.c60
-rw-r--r--common/vboot/vb21_lib.c44
-rw-r--r--common/vboot/vboot.c (renamed from common/vboot.c)105
-rw-r--r--include/vboot.h46
-rw-r--r--power/intel_x86.c2
-rw-r--r--test/build.mk2
-rw-r--r--test/test_config.h20
-rw-r--r--test/vboot.c142
-rw-r--r--test/vboot.tasklist17
11 files changed, 347 insertions, 97 deletions
diff --git a/Makefile b/Makefile
index 2a93daba29..eb089dd566 100644
--- a/Makefile
+++ b/Makefile
@@ -196,6 +196,7 @@ $(eval $(call get_sources,ro))
dirs=core/$(CORE) chip/$(CHIP) $(BDIR) common power test cts/common cts/$(CTS_MODULE)
dirs+= private $(PDIR)
+dirs+=$(shell find common -type d)
dirs+=$(shell find driver -type d)
common_dirs=util
diff --git a/common/build.mk b/common/build.mk
index 7907a87e30..9ceef96bc1 100644
--- a/common/build.mk
+++ b/common/build.mk
@@ -87,7 +87,8 @@ common-$(CONFIG_PWM_KBLIGHT)+=pwm_kblight.o
common-$(CONFIG_RMA_AUTH)+=rma_auth.o
common-$(CONFIG_RSA)+=rsa.o
common-$(CONFIG_ROLLBACK)+=rollback.o
-common-$(CONFIG_RWSIG)+=rwsig.o
+common-$(CONFIG_RWSIG)+=rwsig.o vboot/common.o
+common-$(CONFIG_RWSIG_TYPE_RWSIG)+=vboot/vb21_lib.o
common-$(CONFIG_MATH_UTIL)+=math_util.o
common-$(CONFIG_SHA1)+= sha1.o
common-$(CONFIG_SHA256)+=sha256.o
@@ -112,7 +113,7 @@ common-$(CONFIG_USB_POWER_DELIVERY)+=usb_pd_protocol.o usb_pd_policy.o
common-$(CONFIG_USB_PD_LOGGING)+=pd_log.o
common-$(CONFIG_USB_PD_TCPC)+=usb_pd_tcpc.o
common-$(CONFIG_USB_UPDATE)+=usb_update.o update_fw.o
-common-$(CONFIG_VBOOT_EC)+=vboot.o
+common-$(CONFIG_VBOOT_EC)+=vboot/vboot.o
common-$(CONFIG_VBOOT_HASH)+=sha256.o vboot_hash.o
common-$(CONFIG_VSTORE)+=vstore.o
common-$(CONFIG_WIRELESS)+=wireless.o
diff --git a/common/vboot/common.c b/common/vboot/common.c
new file mode 100644
index 0000000000..3a75a297e6
--- /dev/null
+++ b/common/vboot/common.c
@@ -0,0 +1,60 @@
+/* Copyright 2017 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "common.h"
+#include "console.h"
+#include "rsa.h"
+#include "sha256.h"
+#include "shared_mem.h"
+#include "vboot.h"
+
+#define CPRINTS(format, args...) cprints(CC_VBOOT, format, ## args)
+#define CPRINTF(format, args...) cprintf(CC_VBOOT, format, ## args)
+
+int vboot_is_padding_valid(const uint8_t *data, uint32_t start, uint32_t end)
+{
+ const uint32_t *data32 = (const uint32_t *)data;
+ int i;
+
+ if (start > end)
+ return EC_ERROR_INVAL;
+
+ if (start % 4 || end % 4)
+ return EC_ERROR_INVAL;
+
+ for (i = start / 4; i < end / 4; i++) {
+ if (data32[i] != 0xffffffff)
+ return EC_ERROR_INVAL;
+ }
+
+ return EC_SUCCESS;
+}
+
+int vboot_verify(const uint8_t *data, int len,
+ const struct rsa_public_key *key, const uint8_t *sig)
+{
+ struct sha256_ctx ctx;
+ uint8_t *hash;
+ uint32_t *workbuf;
+ int err = EC_SUCCESS;
+
+ if (shared_mem_acquire(3 * RSANUMBYTES, (char **)&workbuf)) {
+ CPRINTS("Failed to allocate memory");
+ return EC_ERROR_UNKNOWN;
+ }
+
+ /* Compute hash of the RW firmware */
+ SHA256_init(&ctx);
+ SHA256_update(&ctx, data, len);
+ hash = SHA256_final(&ctx);
+
+ /* Verify the data */
+ if (rsa_verify(key, sig, hash, workbuf) != 1)
+ err = EC_ERROR_INVAL;
+
+ shared_mem_release(workbuf);
+
+ return err;
+}
diff --git a/common/vboot/vb21_lib.c b/common/vboot/vb21_lib.c
new file mode 100644
index 0000000000..11242a3038
--- /dev/null
+++ b/common/vboot/vb21_lib.c
@@ -0,0 +1,44 @@
+/* Copyright 2017 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/*
+ * Common utility APIs for vboot 2.1
+ */
+
+#include "common.h"
+#include "rsa.h"
+#include "rwsig.h"
+#include "vb21_struct.h"
+#include "vboot.h"
+
+int vb21_is_packed_key_valid(const struct vb21_packed_key *key)
+{
+ if (key->c.magic != VB21_MAGIC_PACKED_KEY)
+ return EC_ERROR_INVAL;
+ if (key->key_size != sizeof(struct rsa_public_key))
+ return EC_ERROR_INVAL;
+ return EC_SUCCESS;
+}
+
+int vb21_is_signature_valid(const struct vb21_signature *sig,
+ const struct vb21_packed_key *key)
+{
+ if (sig->c.magic != VB21_MAGIC_SIGNATURE)
+ return EC_ERROR_INVAL;
+ if (sig->sig_size != RSANUMBYTES)
+ return EC_ERROR_INVAL;
+ if (key->sig_alg != sig->sig_alg)
+ return EC_ERROR_INVAL;
+ if (key->hash_alg != sig->hash_alg)
+ return EC_ERROR_INVAL;
+ /* Sanity check signature offset and data size. */
+ if (sig->sig_offset < sizeof(*sig))
+ return EC_ERROR_INVAL;
+ if (sig->sig_offset + RSANUMBYTES > CONFIG_RW_SIG_SIZE)
+ return EC_ERROR_INVAL;
+ if (sig->data_size > CONFIG_RW_SIZE - CONFIG_RW_SIG_SIZE)
+ return EC_ERROR_INVAL;
+ return EC_SUCCESS;
+}
diff --git a/common/vboot.c b/common/vboot/vboot.c
index 1e92572c5b..27c57b27c2 100644
--- a/common/vboot.c
+++ b/common/vboot/vboot.c
@@ -22,6 +22,7 @@
#include "vb21_struct.h"
#define CPRINTS(format, args...) cprints(CC_VBOOT, format, ## args)
+#define CPRINTF(format, args...) cprintf(CC_VBOOT, format, ## args)
enum vboot_ec_slot {
VBOOT_EC_SLOT_A,
@@ -47,93 +48,14 @@ static int is_low_power_ap_boot_supported(void)
return 0;
}
-static int is_vb21_packed_key_valid(const struct vb21_packed_key *key)
-{
- if (key->c.magic != VB21_MAGIC_PACKED_KEY)
- return EC_ERROR_INVAL;
- if (key->key_size != sizeof(struct rsa_public_key))
- return EC_ERROR_INVAL;
- return EC_SUCCESS;
-}
-
-static int is_vb21_signature_valid(const struct vb21_signature *sig,
- const struct vb21_packed_key *key)
-{
- if (sig->c.magic != VB21_MAGIC_SIGNATURE)
- return EC_ERROR_INVAL;
- if (sig->sig_size != RSANUMBYTES)
- return EC_ERROR_INVAL;
- if (key->sig_alg != sig->sig_alg)
- return EC_ERROR_INVAL;
- if (key->hash_alg != sig->hash_alg)
- return EC_ERROR_INVAL;
- /* Sanity check signature offset and data size. */
- if (sig->sig_offset < sizeof(*sig))
- return EC_ERROR_INVAL;
- if (sig->sig_offset + RSANUMBYTES > CONFIG_RW_SIG_SIZE)
- return EC_ERROR_INVAL;
- if (sig->data_size > CONFIG_RW_SIZE - CONFIG_RW_SIG_SIZE)
- return EC_ERROR_INVAL;
- return EC_SUCCESS;
-}
-
-static int is_padding_valid(const uint8_t *data, unsigned int start, int len)
-{
- const uint32_t *data32 = (const uint32_t *)data;
- int i;
-
- if (len < 0)
- return EC_ERROR_INVAL;
-
- if ((start % 4) != 0 || (len % 4) != 0)
- return EC_ERROR_INVAL;
-
- for (i = start/4; i < len/4; i++) {
- if (data32[i] != 0xffffffff)
- return EC_ERROR_INVAL;
- }
-
- return EC_SUCCESS;
-}
-
-static int vboot_verify(const uint8_t *data, int len,
- const struct rsa_public_key *key, const uint8_t *sig)
-{
- struct sha256_ctx ctx;
- uint8_t *hash;
- uint32_t *workbuf;
- int err = EC_SUCCESS;
-
- if (shared_mem_acquire(3 * RSANUMBYTES, (char **)&workbuf)) {
- CPRINTS("Failed to allocate memory");
- return EC_ERROR_UNKNOWN;
- }
-
- /* Compute hash of the RW firmware */
- SHA256_init(&ctx);
- SHA256_update(&ctx, data, len);
- hash = SHA256_final(&ctx);
-
- /* Verify the data */
- if (rsa_verify(key, sig, hash, workbuf) != 1) {
- CPRINTS("Invalid data");
- err = EC_ERROR_INVAL;
- }
-
- shared_mem_release(workbuf);
-
- return err;
-}
-
static int verify_slot(int slot)
{
- const uint8_t *data;
const struct vb21_packed_key *vb21_key;
const struct vb21_signature *vb21_sig;
const struct rsa_public_key *key;
const uint8_t *sig;
+ const uint8_t *data;
int len;
- int rv = EC_ERROR_INVAL;
CPRINTS("Verifying RW_%c", slot == VBOOT_EC_SLOT_A ? 'A' : 'B');
@@ -141,9 +63,9 @@ static int verify_slot(int slot)
CONFIG_MAPPED_STORAGE_BASE +
CONFIG_EC_PROTECTED_STORAGE_OFF +
CONFIG_RO_PUBKEY_STORAGE_OFF);
- if (is_vb21_packed_key_valid(vb21_key)) {
+ if (vb21_is_packed_key_valid(vb21_key)) {
CPRINTS("Invalid key");
- goto exit;
+ return EC_ERROR_INVAL;
}
key = (const struct rsa_public_key *)
((const uint8_t *)vb21_key + vb21_key->key_offset);
@@ -166,28 +88,25 @@ static int verify_slot(int slot)
CONFIG_RW_B_SIGN_STORAGE_OFF);
}
- if (is_vb21_signature_valid(vb21_sig, vb21_key)) {
+ if (vb21_is_signature_valid(vb21_sig, vb21_key)) {
CPRINTS("Invalid signature");
- goto exit;
+ return EC_ERROR_INVAL;
}
sig = (const uint8_t *)vb21_sig + vb21_sig->sig_offset;
len = vb21_sig->data_size;
- if (is_padding_valid(data, len,
- CONFIG_RW_SIZE - len - CONFIG_RW_SIG_SIZE)) {
+ if (vboot_is_padding_valid(data, len,
+ CONFIG_RW_SIZE - CONFIG_RW_SIG_SIZE)) {
CPRINTS("Invalid padding");
- goto exit;
+ return EC_ERROR_INVAL;
}
if (vboot_verify(data, len, key, sig)) {
CPRINTS("Invalid data");
- goto exit;
+ return EC_ERROR_INVAL;
}
- rv = EC_SUCCESS;
-
-exit:
- return rv;
+ return EC_SUCCESS;
}
static int verify_and_jump(void)
@@ -238,7 +157,7 @@ static int is_manual_recovery(void)
return host_get_events() & EC_HOST_EVENT_KEYBOARD_RECOVERY;
}
-void vboot_ec(void)
+void vboot_main(void)
{
int port = charge_manager_get_active_charge_port();
diff --git a/include/vboot.h b/include/vboot.h
index ba13328544..14f7a8f13c 100644
--- a/include/vboot.h
+++ b/include/vboot.h
@@ -3,6 +3,50 @@
* found in the LICENSE file.
*/
+#include "common.h"
+#include "vb21_struct.h"
+#include "rsa.h"
+
+/**
+ * Validate key contents.
+ *
+ * @param key
+ * @return EC_SUCCESS or EC_ERROR_*
+ */
+int vb21_is_packed_key_valid(const struct vb21_packed_key *key);
+
+/**
+ * Validate signature contents.
+ *
+ * @param sig Signature to be validated.
+ * @param key Key to be used for validating <sig>.
+ * @return EC_SUCCESS or EC_ERROR_*
+ */
+int vb21_is_signature_valid(const struct vb21_signature *sig,
+ const struct vb21_packed_key *key);
+
+/**
+ * Check data region is filled with ones
+ *
+ * @param data Data to be validated.
+ * @param start Offset where validation starts.
+ * @param end Offset where validation ends. data[end] won't be checked.
+ * @return EC_SUCCESS or EC_ERROR_*
+ */
+int vboot_is_padding_valid(const uint8_t *data, uint32_t start, uint32_t end);
+
+/**
+ * Verify data by RSA signature
+ *
+ * @param data Data to be verified.
+ * @param len Number of bytes in <data>.
+ * @param key Key to be used for verification.
+ * @param sig Signature of <data>
+ * @return EC_SUCCESS or EC_ERROR_*
+ */
+int vboot_verify(const uint8_t *data, int len,
+ const struct rsa_public_key *key, const uint8_t *sig);
+
/**
* Verify RW image and jump to it
*
@@ -12,4 +56,4 @@
* 3. Returns, requesting more power
* 4. Returns, requesting recovery
*/
-void vboot_ec(void);
+void vboot_main(void);
diff --git a/power/intel_x86.c b/power/intel_x86.c
index 5d08397912..90a8682d7c 100644
--- a/power/intel_x86.c
+++ b/power/intel_x86.c
@@ -280,7 +280,7 @@ enum power_state common_intel_x86_power_handle_state(enum power_state state)
*/
{
if (!system_can_boot_ap()) {
- vboot_ec();
+ vboot_main();
while (!system_can_boot_ap())
/* LED blinks as HOOK_TICK events trigger.
* We can print percent & power as they
diff --git a/test/build.mk b/test/build.mk
index 2a1102748d..c54627d03c 100644
--- a/test/build.mk
+++ b/test/build.mk
@@ -79,6 +79,7 @@ test-list-host += usb_pd
test-list-host += usb_pd_giveback
test-list-host += utils
test-list-host += utils_str
+test-list-host += vboot
test-list-host += x25519
endif
@@ -130,4 +131,5 @@ usb_pd-y=usb_pd.o
usb_pd_giveback-y=usb_pd.o
utils-y=utils.o
utils_str-y=utils_str.o
+vboot-y=vboot.o
x25519-y=x25519.o
diff --git a/test/test_config.h b/test/test_config.h
index b90aac3966..5c4807fd66 100644
--- a/test/test_config.h
+++ b/test/test_config.h
@@ -225,6 +225,26 @@ enum nvmem_vars {
#define CONFIG_FLASH_NVMEM_VARS_USER_SIZE 600
#endif /* TEST_NVMEM_VARS */
+#ifdef TEST_VBOOT
+#define CONFIG_RWSIG
+#define CONFIG_SHA256
+#define CONFIG_RSA
+#define CONFIG_RWSIG_TYPE_RWSIG
+#define CONFIG_RW_B
+#define CONFIG_RW_B_MEM_OFF CONFIG_RO_MEM_OFF
+#undef CONFIG_RO_SIZE
+#define CONFIG_RO_SIZE (CONFIG_FLASH_SIZE / 4)
+#undef CONFIG_RW_SIZE
+#define CONFIG_RW_SIZE CONFIG_RO_SIZE
+#define CONFIG_RW_A_STORAGE_OFF CONFIG_RW_STORAGE_OFF
+#define CONFIG_RW_B_STORAGE_OFF (CONFIG_RW_A_STORAGE_OFF + \
+ CONFIG_RW_SIZE)
+#define CONFIG_RW_A_SIGN_STORAGE_OFF (CONFIG_RW_A_STORAGE_OFF + \
+ CONFIG_RW_SIZE - CONFIG_RW_SIG_SIZE)
+#define CONFIG_RW_B_SIGN_STORAGE_OFF (CONFIG_RW_B_STORAGE_OFF + \
+ CONFIG_RW_SIZE - CONFIG_RW_SIG_SIZE)
+#endif
+
#ifdef TEST_X25519
#define CONFIG_CURVE25519
#endif /* TEST_X25519 */
diff --git a/test/vboot.c b/test/vboot.c
new file mode 100644
index 0000000000..3d4be10308
--- /dev/null
+++ b/test/vboot.c
@@ -0,0 +1,142 @@
+/* Copyright 2017 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Test vboot
+ */
+
+#include <stdlib.h>
+#include "common.h"
+#include "rsa.h"
+#include "test_util.h"
+#include "vboot.h"
+#include "rsa2048-3.h"
+#include "rwsig.h"
+
+struct vboot_key {
+ struct vb21_packed_key vb21_key;
+ struct rsa_public_key key_data;
+};
+
+struct vboot_sig {
+ struct vb21_signature vb21_sig;
+ uint8_t sig_data[RSANUMBYTES];
+};
+
+static void reset_data(struct vboot_key *k, struct vboot_sig *s)
+{
+ k->vb21_key.c.magic = VB21_MAGIC_PACKED_KEY;
+ k->vb21_key.key_offset = sizeof(struct vb21_packed_key);
+ k->vb21_key.key_size = sizeof(rsa_data);
+ memcpy(&k->key_data, rsa_data, sizeof(rsa_data));
+
+ s->vb21_sig.c.magic = VB21_MAGIC_SIGNATURE;
+ s->vb21_sig.sig_size = RSANUMBYTES;
+ s->vb21_sig.sig_offset = sizeof(struct vb21_signature);
+ s->vb21_sig.sig_alg = k->vb21_key.sig_alg;
+ s->vb21_sig.hash_alg = k->vb21_key.hash_alg;
+ s->vb21_sig.data_size = CONFIG_RW_SIZE - CONFIG_RW_SIG_SIZE - 32;
+ memcpy(s->sig_data, sig, sizeof(s->sig_data));
+}
+
+static int test_vboot(void)
+{
+ struct vboot_key k;
+ struct vboot_sig s;
+ uint8_t data[CONFIG_RW_SIZE];
+ int len;
+ int err;
+
+ /* Success */
+ reset_data(&k, &s);
+ memset(data, 0xff, CONFIG_RW_SIZE);
+ err = vb21_is_packed_key_valid(&k.vb21_key);
+ TEST_ASSERT(err == EC_SUCCESS);
+ err = vb21_is_signature_valid(&s.vb21_sig, &k.vb21_key);
+ TEST_ASSERT(err == EC_SUCCESS);
+ len = s.vb21_sig.data_size;
+ err = vboot_is_padding_valid(data, len,
+ CONFIG_RW_SIZE - CONFIG_RW_SIG_SIZE);
+ TEST_ASSERT(err == EC_SUCCESS);
+
+ /* Invalid magic */
+ reset_data(&k, &s);
+ k.vb21_key.c.magic = VB21_MAGIC_SIGNATURE;
+ err = vb21_is_packed_key_valid(&k.vb21_key);
+ TEST_ASSERT(err == EC_ERROR_INVAL);
+
+ /* Invalid key size */
+ reset_data(&k, &s);
+ k.vb21_key.key_size--;
+ err = vb21_is_packed_key_valid(&k.vb21_key);
+ TEST_ASSERT(err == EC_ERROR_INVAL);
+
+ /* Invalid magic */
+ reset_data(&k, &s);
+ s.vb21_sig.c.magic = VB21_MAGIC_PACKED_KEY;
+ err = vb21_is_signature_valid(&s.vb21_sig, &k.vb21_key);
+ TEST_ASSERT(err == EC_ERROR_INVAL);
+
+ /* Invalid sig size */
+ reset_data(&k, &s);
+ s.vb21_sig.sig_size--;
+ err = vb21_is_signature_valid(&s.vb21_sig, &k.vb21_key);
+ TEST_ASSERT(err == EC_ERROR_INVAL);
+
+ /* Sig algorithm mismatch */
+ reset_data(&k, &s);
+ s.vb21_sig.sig_alg++;
+ err = vb21_is_signature_valid(&s.vb21_sig, &k.vb21_key);
+ TEST_ASSERT(err == EC_ERROR_INVAL);
+
+ /* Hash algorithm mismatch */
+ reset_data(&k, &s);
+ s.vb21_sig.hash_alg++;
+ err = vb21_is_signature_valid(&s.vb21_sig, &k.vb21_key);
+ TEST_ASSERT(err == EC_ERROR_INVAL);
+
+ /* Invalid sig_offset */
+ reset_data(&k, &s);
+ s.vb21_sig.sig_offset--;
+ err = vb21_is_signature_valid(&s.vb21_sig, &k.vb21_key);
+ TEST_ASSERT(err == EC_ERROR_INVAL);
+
+ /* Invalid data size */
+ reset_data(&k, &s);
+ s.vb21_sig.data_size = CONFIG_RW_SIZE;
+ err = vb21_is_signature_valid(&s.vb21_sig, &k.vb21_key);
+ TEST_ASSERT(err == EC_ERROR_INVAL);
+
+ /* Invalid padding */
+ reset_data(&k, &s);
+ len = s.vb21_sig.data_size;
+ data[len] = 0;
+ err = vboot_is_padding_valid(data, len,
+ CONFIG_RW_SIZE - CONFIG_RW_SIG_SIZE);
+ TEST_ASSERT(err == EC_ERROR_INVAL);
+
+ /* Invalid padding size */
+ reset_data(&k, &s);
+ len = s.vb21_sig.data_size + 1;
+ err = vboot_is_padding_valid(data, len,
+ CONFIG_RW_SIZE - CONFIG_RW_SIG_SIZE);
+ TEST_ASSERT(err == EC_ERROR_INVAL);
+
+ /* Padding size is too large */
+ reset_data(&k, &s);
+ len = s.vb21_sig.data_size + 64;
+ err = vboot_is_padding_valid(data, len,
+ CONFIG_RW_SIZE - CONFIG_RW_SIG_SIZE);
+ TEST_ASSERT(err == EC_ERROR_INVAL);
+
+ return EC_SUCCESS;
+}
+
+void run_test(void)
+{
+ test_reset();
+
+ RUN_TEST(test_vboot);
+
+ test_print_result();
+}
diff --git a/test/vboot.tasklist b/test/vboot.tasklist
new file mode 100644
index 0000000000..e241aab4bb
--- /dev/null
+++ b/test/vboot.tasklist
@@ -0,0 +1,17 @@
+/* Copyright 2017 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**
+ * List of enabled tasks in the priority order
+ *
+ * The first one has the lowest priority.
+ *
+ * For each task, use the macro TASK_TEST(n, r, d, s) where :
+ * 'n' in the name of the task
+ * 'r' in the main routine of the task
+ * 'd' in an opaque parameter passed to the routine at startup
+ * 's' is the stack size in bytes; must be a multiple of 8
+ */
+#define CONFIG_TEST_TASK_LIST /* No test task */