mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-11-27 11:44:02 +00:00
vboot2: Add support for kernel version secure data space
Holds kernel rollback information. Will be used by vboot 2.0 kernel verification. BUG=chromium:487699 BRANCH=none TEST=make -j runtests Change-Id: Ib4a70e943ebd79aac06404df09cf4ce62d719201 Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/270626 Reviewed-by: Bill Richardson <wfrichar@chromium.org>
This commit is contained in:
committed by
ChromeOS Commit Bot
parent
0140cd2906
commit
bf9c2760d2
3
Makefile
3
Makefile
@@ -330,6 +330,7 @@ FWLIB2X_SRCS = \
|
||||
firmware/2lib/2nvstorage.c \
|
||||
firmware/2lib/2rsa.c \
|
||||
firmware/2lib/2secdata.c \
|
||||
firmware/2lib/2secdatak.c \
|
||||
firmware/2lib/2sha1.c \
|
||||
firmware/2lib/2sha256.c \
|
||||
firmware/2lib/2sha512.c \
|
||||
@@ -711,6 +712,7 @@ TEST2X_NAMES = \
|
||||
tests/vb2_nvstorage_tests \
|
||||
tests/vb2_rsa_utility_tests \
|
||||
tests/vb2_secdata_tests \
|
||||
tests/vb2_secdatak_tests \
|
||||
tests/vb2_sha_tests
|
||||
|
||||
TEST20_NAMES = \
|
||||
@@ -1376,6 +1378,7 @@ run2tests: test_setup
|
||||
${RUNTEST} ${BUILD_RUN}/tests/vb2_nvstorage_tests
|
||||
${RUNTEST} ${BUILD_RUN}/tests/vb2_rsa_utility_tests
|
||||
${RUNTEST} ${BUILD_RUN}/tests/vb2_secdata_tests
|
||||
${RUNTEST} ${BUILD_RUN}/tests/vb2_secdatak_tests
|
||||
${RUNTEST} ${BUILD_RUN}/tests/vb2_sha_tests
|
||||
${RUNTEST} ${BUILD_RUN}/tests/vb20_api_tests
|
||||
${RUNTEST} ${BUILD_RUN}/tests/vb20_common_tests
|
||||
|
||||
112
firmware/2lib/2secdatak.c
Normal file
112
firmware/2lib/2secdatak.c
Normal file
@@ -0,0 +1,112 @@
|
||||
/* Copyright 2015 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.
|
||||
*
|
||||
* Secure storage APIs - kernel version space
|
||||
*/
|
||||
|
||||
#include "2sysincludes.h"
|
||||
#include "2common.h"
|
||||
#include "2crc8.h"
|
||||
#include "2misc.h"
|
||||
#include "2secdata.h"
|
||||
|
||||
int vb2_secdatak_check_crc(const struct vb2_context *ctx)
|
||||
{
|
||||
const struct vb2_secdatak *sec =
|
||||
(const struct vb2_secdatak *)ctx->secdatak;
|
||||
|
||||
/* Verify CRC */
|
||||
if (sec->crc8 != vb2_crc8(sec, offsetof(struct vb2_secdatak, crc8)))
|
||||
return VB2_ERROR_SECDATAK_CRC;
|
||||
|
||||
return VB2_SUCCESS;
|
||||
}
|
||||
|
||||
int vb2_secdatak_create(struct vb2_context *ctx)
|
||||
{
|
||||
struct vb2_secdatak *sec = (struct vb2_secdatak *)ctx->secdatak;
|
||||
|
||||
/* Clear the entire struct */
|
||||
memset(sec, 0, sizeof(*sec));
|
||||
|
||||
/* Set to current version */
|
||||
sec->struct_version = VB2_SECDATAK_VERSION;
|
||||
|
||||
/* Set UID */
|
||||
sec->uid = VB2_SECDATAK_UID;
|
||||
|
||||
/* Calculate initial CRC */
|
||||
sec->crc8 = vb2_crc8(sec, offsetof(struct vb2_secdatak, crc8));
|
||||
ctx->flags |= VB2_CONTEXT_SECDATAK_CHANGED;
|
||||
return VB2_SUCCESS;
|
||||
}
|
||||
|
||||
int vb2_secdatak_init(struct vb2_context *ctx)
|
||||
{
|
||||
struct vb2_secdatak *sec = (struct vb2_secdatak *)ctx->secdatak;
|
||||
struct vb2_shared_data *sd = vb2_get_sd(ctx);
|
||||
int rv;
|
||||
|
||||
rv = vb2_secdatak_check_crc(ctx);
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
/* Make sure the UID is correct */
|
||||
if (sec->uid != VB2_SECDATAK_UID)
|
||||
return VB2_ERROR_SECDATAK_UID;
|
||||
|
||||
/* Set status flag */
|
||||
sd->status |= VB2_SD_STATUS_SECDATAK_INIT;
|
||||
/* TODO: unit test for that */
|
||||
|
||||
return VB2_SUCCESS;
|
||||
}
|
||||
|
||||
int vb2_secdatak_get(struct vb2_context *ctx,
|
||||
enum vb2_secdatak_param param,
|
||||
uint32_t *dest)
|
||||
{
|
||||
struct vb2_secdatak *sec = (struct vb2_secdatak *)ctx->secdatak;
|
||||
|
||||
if (!(vb2_get_sd(ctx)->status & VB2_SD_STATUS_SECDATAK_INIT))
|
||||
return VB2_ERROR_SECDATAK_GET_UNINITIALIZED;
|
||||
|
||||
switch(param) {
|
||||
case VB2_SECDATAK_VERSIONS:
|
||||
*dest = sec->kernel_versions;
|
||||
return VB2_SUCCESS;
|
||||
|
||||
default:
|
||||
return VB2_ERROR_SECDATAK_GET_PARAM;
|
||||
}
|
||||
}
|
||||
|
||||
int vb2_secdatak_set(struct vb2_context *ctx,
|
||||
enum vb2_secdatak_param param,
|
||||
uint32_t value)
|
||||
{
|
||||
struct vb2_secdatak *sec = (struct vb2_secdatak *)ctx->secdatak;
|
||||
uint32_t now;
|
||||
|
||||
if (!(vb2_get_sd(ctx)->status & VB2_SD_STATUS_SECDATAK_INIT))
|
||||
return VB2_ERROR_SECDATAK_SET_UNINITIALIZED;
|
||||
|
||||
/* If not changing the value, don't regenerate the CRC. */
|
||||
if (vb2_secdatak_get(ctx, param, &now) == VB2_SUCCESS && now == value)
|
||||
return VB2_SUCCESS;
|
||||
|
||||
switch(param) {
|
||||
case VB2_SECDATAK_VERSIONS:
|
||||
sec->kernel_versions = value;
|
||||
break;
|
||||
|
||||
default:
|
||||
return VB2_ERROR_SECDATAK_SET_PARAM;
|
||||
}
|
||||
|
||||
/* Regenerate CRC */
|
||||
sec->crc8 = vb2_crc8(sec, offsetof(struct vb2_secdatak, crc8));
|
||||
ctx->flags |= VB2_CONTEXT_SECDATAK_CHANGED;
|
||||
return VB2_SUCCESS;
|
||||
}
|
||||
@@ -31,8 +31,9 @@
|
||||
/* Size of non-volatile data used by vboot */
|
||||
#define VB2_NVDATA_SIZE 16
|
||||
|
||||
/* Size of secure data used by vboot */
|
||||
/* Size of secure data spaces used by vboot */
|
||||
#define VB2_SECDATA_SIZE 10
|
||||
#define VB2_SECDATAK_SIZE 14
|
||||
|
||||
/*
|
||||
* Recommended size of work buffer.
|
||||
@@ -93,6 +94,12 @@ enum vb2_context_flags {
|
||||
|
||||
/* Erase TPM developer mode state if it is enabled. */
|
||||
VB2_DISABLE_DEVELOPER_MODE = (1 << 9),
|
||||
|
||||
/*
|
||||
* Verified boot has changed secdatak[]. Caller must save secdatak[]
|
||||
* back to its underlying storage, then may clear this flag.
|
||||
*/
|
||||
VB2_CONTEXT_SECDATAK_CHANGED = (1 << 11),
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -128,10 +135,11 @@ struct vb2_context {
|
||||
uint8_t nvdata[VB2_NVDATA_SIZE];
|
||||
|
||||
/*
|
||||
* Secure data. Caller must fill this from some secure non-volatile
|
||||
* location. If the VB2_CONTEXT_SECDATA_CHANGED flag is set when a
|
||||
* function returns, caller must save the data back to the secure
|
||||
* non-volatile location and then clear the flag.
|
||||
* Secure data for firmware verification stage. Caller must fill this
|
||||
* from some secure non-volatile location. If the
|
||||
* VB2_CONTEXT_SECDATA_CHANGED flag is set when a function returns,
|
||||
* caller must save the data back to the secure non-volatile location
|
||||
* and then clear the flag.
|
||||
*/
|
||||
uint8_t secdata[VB2_SECDATA_SIZE];
|
||||
|
||||
@@ -154,6 +162,19 @@ struct vb2_context {
|
||||
* copied when relocating the work buffer.
|
||||
*/
|
||||
uint32_t workbuf_used;
|
||||
|
||||
/**********************************************************************
|
||||
* Fields caller must initialize before calling vb2api_kernel_phase1().
|
||||
*/
|
||||
|
||||
/*
|
||||
* Secure data for kernel verification stage. Caller must fill this
|
||||
* from some secure non-volatile location. If the
|
||||
* VB2_CONTEXT_SECDATAK_CHANGED flag is set when a function returns,
|
||||
* caller must save the data back to the secure non-volatile location
|
||||
* and then clear the flag.
|
||||
*/
|
||||
uint8_t secdatak[VB2_SECDATAK_SIZE];
|
||||
};
|
||||
|
||||
enum vb2_resource_index {
|
||||
@@ -234,8 +255,7 @@ enum vb2_pcr_digest {
|
||||
*
|
||||
* At this point, firmware verification is done, and vb2_context contains the
|
||||
* kernel key needed to verify the kernel. That context should be preserved
|
||||
* and passed on to kernel selection. For now, that requires translating it
|
||||
* into the old VbSharedData format (via a func which does not yet exist...)
|
||||
* and passed on to kernel selection.
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -266,6 +286,34 @@ int vb2api_secdata_check(const struct vb2_context *ctx);
|
||||
*/
|
||||
int vb2api_secdata_create(struct vb2_context *ctx);
|
||||
|
||||
/**
|
||||
* Sanity-check the contents of the kernel version secure storage context.
|
||||
*
|
||||
* Use this if reading from secure storage may be flaky, and you want to retry
|
||||
* reading it several times.
|
||||
*
|
||||
* This may be called before vb2api_phase1().
|
||||
*
|
||||
* @param ctx Context pointer
|
||||
* @return VB2_SUCCESS, or non-zero error code if error.
|
||||
*/
|
||||
int vb2api_secdatak_check(const struct vb2_context *ctx);
|
||||
|
||||
/**
|
||||
* Create fresh data in the kernel version secure storage context.
|
||||
*
|
||||
* Use this only when initializing the secure storage context on a new machine
|
||||
* the first time it boots. Do NOT simply use this if vb2api_secdatak_check()
|
||||
* (or any other API in this library) fails; that could allow the secure data
|
||||
* to be rolled back to an insecure state.
|
||||
*
|
||||
* This may be called before vb2api_phase1().
|
||||
*
|
||||
* @param ctx Context pointer
|
||||
* @return VB2_SUCCESS, or non-zero error code if error.
|
||||
*/
|
||||
int vb2api_secdatak_create(struct vb2_context *ctx);
|
||||
|
||||
/**
|
||||
* Report firmware failure to vboot.
|
||||
*
|
||||
|
||||
@@ -111,6 +111,30 @@ enum vb2_return_code {
|
||||
/* Called vb2_secdata_set() with uninitialized secdata */
|
||||
VB2_ERROR_SECDATA_SET_UNINITIALIZED,
|
||||
|
||||
/* Bad CRC in vb2_secdatak_check_crc() */
|
||||
VB2_ERROR_SECDATAK_CRC,
|
||||
|
||||
/* Bad struct version in vb2_secdatak_init() */
|
||||
VB2_ERROR_SECDATAK_VERSION,
|
||||
|
||||
/* Bad uid in vb2_secdatak_init() */
|
||||
VB2_ERROR_SECDATAK_UID,
|
||||
|
||||
/* Invalid param in vb2_secdatak_get() */
|
||||
VB2_ERROR_SECDATAK_GET_PARAM,
|
||||
|
||||
/* Invalid param in vb2_secdatak_set() */
|
||||
VB2_ERROR_SECDATAK_SET_PARAM,
|
||||
|
||||
/* Invalid flags passed to vb2_secdatak_set() */
|
||||
VB2_ERROR_SECDATAK_SET_FLAGS,
|
||||
|
||||
/* Called vb2_secdatak_get() with uninitialized secdatak */
|
||||
VB2_ERROR_SECDATAK_GET_UNINITIALIZED,
|
||||
|
||||
/* Called vb2_secdatak_set() with uninitialized secdatak */
|
||||
VB2_ERROR_SECDATAK_SET_UNINITIALIZED,
|
||||
|
||||
/**********************************************************************
|
||||
* Common code errors
|
||||
*/
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
#ifndef VBOOT_REFERENCE_VBOOT_SECDATA_H_
|
||||
#define VBOOT_REFERENCE_VBOOT_SECDATA_H_
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Firmware version space */
|
||||
|
||||
/* Expected value of vb2_secdata.version */
|
||||
#define VB2_SECDATA_VERSION 2
|
||||
|
||||
@@ -28,7 +31,7 @@ enum vb2_secdata_flags {
|
||||
VB2_SECDATA_FLAG_DEV_MODE = (1 << 1),
|
||||
};
|
||||
|
||||
/* Secure data area */
|
||||
/* Secure data area (firmware space) */
|
||||
struct vb2_secdata {
|
||||
/* Struct version, for backwards compatibility */
|
||||
uint8_t struct_version;
|
||||
@@ -55,6 +58,39 @@ enum vb2_secdata_param {
|
||||
VB2_SECDATA_VERSIONS,
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Kernel version space */
|
||||
|
||||
/* Kernel space - KERNEL_NV_INDEX, locked with physical presence. */
|
||||
#define VB2_SECDATAK_VERSION 2
|
||||
#define VB2_SECDATAK_UID 0x4752574c /* 'GRWL' */
|
||||
|
||||
struct vb2_secdatak {
|
||||
/* Struct version, for backwards compatibility */
|
||||
uint8_t struct_version;
|
||||
|
||||
/* Unique ID to detect space redefinition */
|
||||
uint32_t uid;
|
||||
|
||||
/* Kernel versions */
|
||||
uint32_t kernel_versions;
|
||||
|
||||
/* Reserved for future expansion */
|
||||
uint8_t reserved[3];
|
||||
|
||||
/* CRC; must be last field in struct */
|
||||
uint8_t crc8;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Which param to get/set for vb2_secdatak_get() / vb2_secdatak_set() */
|
||||
enum vb2_secdatak_param {
|
||||
/* Kernel versions */
|
||||
VB2_SECDATAK_VERSIONS = 0,
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Firmware version space functions */
|
||||
|
||||
/**
|
||||
* Check the CRC of the secure storage context.
|
||||
*
|
||||
@@ -114,4 +150,70 @@ int vb2_secdata_set(struct vb2_context *ctx,
|
||||
enum vb2_secdata_param param,
|
||||
uint32_t value);
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Kernel version space functions.
|
||||
*
|
||||
* These are separate functions so that they don't bloat the size of the early
|
||||
* boot code which uses the firmware version space functions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Check the CRC of the kernel version secure storage context.
|
||||
*
|
||||
* Use this if reading from secure storage may be flaky, and you want to retry
|
||||
* reading it several times.
|
||||
*
|
||||
* This may be called before vb2_context_init().
|
||||
*
|
||||
* @param ctx Context pointer
|
||||
* @return VB2_SUCCESS, or non-zero error code if error.
|
||||
*/
|
||||
int vb2_secdatak_check_crc(const struct vb2_context *ctx);
|
||||
|
||||
/**
|
||||
* Create fresh data in the secure storage context.
|
||||
*
|
||||
* Use this only when initializing the secure storage context on a new machine
|
||||
* the first time it boots. Do NOT simply use this if vb2_secdatak_check_crc()
|
||||
* (or any other API in this library) fails; that could allow the secure data
|
||||
* to be rolled back to an insecure state.
|
||||
*
|
||||
* This may be called before vb2_context_init().
|
||||
*/
|
||||
int vb2_secdatak_create(struct vb2_context *ctx);
|
||||
|
||||
/**
|
||||
* Initialize the secure storage context and verify its CRC.
|
||||
*
|
||||
* This must be called before vb2_secdatak_get() or vb2_secdatak_set().
|
||||
*
|
||||
* @param ctx Context pointer
|
||||
* @return VB2_SUCCESS, or non-zero error code if error.
|
||||
*/
|
||||
int vb2_secdatak_init(struct vb2_context *ctx);
|
||||
|
||||
/**
|
||||
* Read a secure storage value.
|
||||
*
|
||||
* @param ctx Context pointer
|
||||
* @param param Parameter to read
|
||||
* @param dest Destination for value
|
||||
* @return VB2_SUCCESS, or non-zero error code if error.
|
||||
*/
|
||||
int vb2_secdatak_get(struct vb2_context *ctx,
|
||||
enum vb2_secdatak_param param,
|
||||
uint32_t *dest);
|
||||
|
||||
/**
|
||||
* Write a secure storage value.
|
||||
*
|
||||
* @param ctx Context pointer
|
||||
* @param param Parameter to write
|
||||
* @param value New value
|
||||
* @return VB2_SUCCESS, or non-zero error code if error.
|
||||
*/
|
||||
int vb2_secdatak_set(struct vb2_context *ctx,
|
||||
enum vb2_secdatak_param param,
|
||||
uint32_t value);
|
||||
|
||||
#endif /* VBOOT_REFERENCE_VBOOT_2SECDATA_H_ */
|
||||
|
||||
@@ -52,6 +52,9 @@ enum vb2_shared_data_status {
|
||||
|
||||
/* Chose a firmware slot */
|
||||
VB2_SD_STATUS_CHOSE_SLOT = (1 << 3),
|
||||
|
||||
/* Secure data kernel version space initialized */
|
||||
VB2_SD_STATUS_SECDATAK_INIT = (1 << 4),
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
114
tests/vb2_secdatak_tests.c
Normal file
114
tests/vb2_secdatak_tests.c
Normal file
@@ -0,0 +1,114 @@
|
||||
/* Copyright 2015 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.
|
||||
*
|
||||
* Tests for kernel secure storage library.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "test_common.h"
|
||||
#include "vboot_common.h"
|
||||
|
||||
#include "2common.h"
|
||||
#include "2api.h"
|
||||
#include "2crc8.h"
|
||||
#include "2misc.h"
|
||||
#include "2secdata.h"
|
||||
|
||||
static void test_changed(struct vb2_context *ctx, int changed, const char *why)
|
||||
{
|
||||
if (changed)
|
||||
TEST_NEQ(ctx->flags & VB2_CONTEXT_SECDATAK_CHANGED, 0, why);
|
||||
else
|
||||
TEST_EQ(ctx->flags & VB2_CONTEXT_SECDATAK_CHANGED, 0, why);
|
||||
|
||||
ctx->flags &= ~VB2_CONTEXT_SECDATAK_CHANGED;
|
||||
};
|
||||
|
||||
static void secdatak_test(void)
|
||||
{
|
||||
uint8_t workbuf[VB2_WORKBUF_RECOMMENDED_SIZE]
|
||||
__attribute__ ((aligned (VB2_WORKBUF_ALIGN)));
|
||||
struct vb2_context c = {
|
||||
.flags = 0,
|
||||
.workbuf = workbuf,
|
||||
.workbuf_size = sizeof(workbuf),
|
||||
};
|
||||
uint32_t v = 1;
|
||||
|
||||
/* Blank data is invalid */
|
||||
memset(c.secdatak, 0xa6, sizeof(c.secdatak));
|
||||
TEST_EQ(vb2_secdatak_check_crc(&c),
|
||||
VB2_ERROR_SECDATAK_CRC, "Check blank CRC");
|
||||
TEST_EQ(vb2_secdatak_init(&c),
|
||||
VB2_ERROR_SECDATAK_CRC, "Init blank CRC");
|
||||
|
||||
/* Create good data */
|
||||
TEST_SUCC(vb2_secdatak_create(&c), "Create");
|
||||
TEST_SUCC(vb2_secdatak_check_crc(&c), "Check created CRC");
|
||||
TEST_SUCC(vb2_secdatak_init(&c), "Init created CRC");
|
||||
test_changed(&c, 1, "Create changes data");
|
||||
|
||||
/* Now corrupt it */
|
||||
c.secdatak[2]++;
|
||||
TEST_EQ(vb2_secdatak_check_crc(&c),
|
||||
VB2_ERROR_SECDATAK_CRC, "Check invalid CRC");
|
||||
TEST_EQ(vb2_secdatak_init(&c),
|
||||
VB2_ERROR_SECDATAK_CRC, "Init invalid CRC");
|
||||
|
||||
/* Make sure UID is checked */
|
||||
{
|
||||
struct vb2_secdatak *sec = (struct vb2_secdatak *)c.secdatak;
|
||||
|
||||
vb2_secdatak_create(&c);
|
||||
sec->uid++;
|
||||
sec->crc8 = vb2_crc8(sec, offsetof(struct vb2_secdatak, crc8));
|
||||
|
||||
TEST_EQ(vb2_secdatak_init(&c), VB2_ERROR_SECDATAK_UID,
|
||||
"Init invalid struct UID");
|
||||
}
|
||||
|
||||
/* Read/write versions */
|
||||
vb2_secdatak_create(&c);
|
||||
c.flags = 0;
|
||||
TEST_SUCC(vb2_secdatak_get(&c, VB2_SECDATAK_VERSIONS, &v),
|
||||
"Get versions");
|
||||
TEST_EQ(v, 0, "Versions created 0");
|
||||
test_changed(&c, 0, "Get doesn't change data");
|
||||
TEST_SUCC(vb2_secdatak_set(&c, VB2_SECDATAK_VERSIONS, 0x123456ff),
|
||||
"Set versions");
|
||||
test_changed(&c, 1, "Set changes data");
|
||||
TEST_SUCC(vb2_secdatak_set(&c, VB2_SECDATAK_VERSIONS, 0x123456ff),
|
||||
"Set versions 2");
|
||||
test_changed(&c, 0, "Set again doesn't change data");
|
||||
TEST_SUCC(vb2_secdatak_get(&c, VB2_SECDATAK_VERSIONS, &v),
|
||||
"Get versions 2");
|
||||
TEST_EQ(v, 0x123456ff, "Versions changed");
|
||||
|
||||
/* Invalid field fails */
|
||||
TEST_EQ(vb2_secdatak_get(&c, -1, &v),
|
||||
VB2_ERROR_SECDATAK_GET_PARAM, "Get invalid");
|
||||
TEST_EQ(vb2_secdatak_set(&c, -1, 456),
|
||||
VB2_ERROR_SECDATAK_SET_PARAM, "Set invalid");
|
||||
test_changed(&c, 0, "Set invalid field doesn't change data");
|
||||
|
||||
/* Read/write uninitialized data fails */
|
||||
vb2_get_sd(&c)->status &= ~VB2_SD_STATUS_SECDATAK_INIT;
|
||||
TEST_EQ(vb2_secdatak_get(&c, VB2_SECDATAK_VERSIONS, &v),
|
||||
VB2_ERROR_SECDATAK_GET_UNINITIALIZED, "Get uninitialized");
|
||||
test_changed(&c, 0, "Get uninitialized doesn't change data");
|
||||
TEST_EQ(vb2_secdatak_set(&c, VB2_SECDATAK_VERSIONS, 0x123456ff),
|
||||
VB2_ERROR_SECDATAK_SET_UNINITIALIZED, "Set uninitialized");
|
||||
test_changed(&c, 0, "Set uninitialized doesn't change data");
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
secdatak_test();
|
||||
|
||||
return gTestSuccess ? 0 : 255;
|
||||
}
|
||||
Reference in New Issue
Block a user