Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
adam.huang
Arm Trusted Firmware
Commits
82ed37ee
Commit
82ed37ee
authored
Feb 10, 2020
by
Olivier Deprez
Committed by
TrustedFirmware Code Review
Feb 10, 2020
Browse files
Merge "SPM: modify sptool to generate individual SP blobs" into integration
parents
ea25ce90
3977a825
Changes
2
Hide whitespace changes
Inline
Side-by-side
include/tools_share/sptool.h
View file @
82ed37ee
/*
* Copyright (c) 2018, Arm Limited. All rights reserved.
* Copyright (c) 2018
-2020
, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
...
...
@@ -9,21 +9,17 @@
#include <stdint.h>
/* Header for a secure partition package. There is one per package. */
struct
sp_pkg_header
{
uint64_t
version
;
uint64_t
number_of_sp
;
};
/* 4 Byte magic name "SPKG" */
#define SECURE_PARTITION_MAGIC 0x474B5053
/*
* Entry descriptor in a secure partition package. Each entry comprises a
* secure partition and its resource description.
*/
struct
sp_pkg_entry
{
uint64_t
sp_offset
;
uint64_t
sp_size
;
uint64_t
rd_offset
;
uint64_t
rd_size
;
/* Header for a secure partition package. */
struct
sp_pkg_header
{
uint32_t
magic
;
uint32_t
version
;
uint32_t
pm_offset
;
uint32_t
pm_size
;
uint32_t
img_offset
;
uint32_t
img_size
;
};
#endif
/* SPTOOL_H */
tools/sptool/sptool.c
View file @
82ed37ee
/*
* Copyright (c) 2018, Arm Limited. All rights reserved.
* Copyright (c) 2018
-2020
, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
...
...
@@ -16,25 +17,26 @@
#define PAGE_SIZE 4096
/*
* Linked list of entries describing entries in the secure
* partition package.
* Entry describing Secure Partition package.
*/
struct
sp_
entry
_info
{
struct
sp_
pkg
_info
{
/* Location of the files in the host's RAM. */
void
*
sp
_data
,
*
rd
_data
;
void
*
img
_data
,
*
pm
_data
;
/* Size of the files. */
uint
64
_t
sp
_size
,
rd
_size
;
uint
32
_t
img
_size
,
pm
_size
;
/* Location of the binary files inside the package output file */
uint64_t
sp_offset
,
rd_offset
;
struct
sp_entry_info
*
next
;
uint32_t
img_offset
,
pm_offset
;
};
static
struct
sp_entry_info
*
sp_info_head
;
static
uint64_t
sp_count
;
/*
* List of input provided by user
*/
struct
arg_list
{
char
*
usr_input
;
struct
arg_list
*
next
;
};
/* Align an address to a power-of-two boundary. */
static
unsigned
int
align_to
(
unsigned
int
address
,
unsigned
int
boundary
)
...
...
@@ -89,26 +91,61 @@ static void xfseek(FILE *fp, long offset, int whence)
}
}
static
void
cleanup
(
void
)
/*
* Free SP package structure
*/
static
void
cleanup
(
struct
sp_pkg_info
*
sp
)
{
struct
sp_entry_info
*
sp
=
sp_info_head
;
while
(
sp
!=
NULL
)
{
struct
sp_entry_info
*
next
=
sp
->
next
;
if
(
sp
->
sp_data
!=
NULL
)
free
(
sp
->
sp_data
);
if
(
sp
!=
NULL
)
{
if
(
sp
->
img_data
!=
NULL
)
{
free
(
sp
->
img_data
);
}
if
(
sp
->
rd_data
!=
NULL
)
free
(
sp
->
rd_data
);
if
(
sp
->
pm_data
!=
NULL
)
{
free
(
sp
->
pm_data
);
}
free
(
sp
);
sp
=
next
;
}
}
sp_count
=
0
;
sp_info_head
=
NULL
;
/*
* Free argument list structure
*/
static
void
freelist
(
struct
arg_list
*
head
)
{
struct
arg_list
*
tmp
;
while
(
head
!=
NULL
)
{
tmp
=
head
;
head
=
head
->
next
;
free
(
tmp
);
}
}
/*
* Append user inputs in argument list structure
*/
static
void
append_user_input
(
struct
arg_list
**
head
,
char
*
args
)
{
struct
arg_list
*
tmp
=
*
head
;
if
(
tmp
==
NULL
)
{
tmp
=
xzalloc
(
sizeof
(
struct
arg_list
),
"Failed to allocate arg_list struct"
);
tmp
->
usr_input
=
args
;
*
head
=
tmp
;
}
else
{
while
(
tmp
->
next
!=
NULL
)
{
tmp
=
tmp
->
next
;
}
tmp
->
next
=
xzalloc
(
sizeof
(
struct
arg_list
),
"Failed to allocate arg_list struct"
);
tmp
=
tmp
->
next
;
tmp
->
usr_input
=
args
;
}
}
/*
...
...
@@ -116,7 +153,7 @@ static void cleanup(void)
* load the file into it. Fill 'size' with the file size. Exit the program on
* error.
*/
static
void
load_file
(
const
char
*
path
,
void
**
ptr
,
uint
64
_t
*
size
)
static
void
load_file
(
const
char
*
path
,
void
**
ptr
,
uint
32
_t
*
size
)
{
FILE
*
f
=
fopen
(
path
,
"rb"
);
if
(
f
==
NULL
)
{
...
...
@@ -147,59 +184,40 @@ static void load_file(const char *path, void **ptr, uint64_t *size)
fclose
(
f
);
}
static
void
load_sp_rd
(
char
*
path
)
/*
* Parse the string containing input payloads and fill in the
* SP Package data structure.
*/
static
void
load_sp_pm
(
char
*
path
,
struct
sp_pkg_info
**
sp_out
)
{
struct
sp_pkg_info
*
sp_pkg
;
char
*
split_mark
=
strstr
(
path
,
":"
);
*
split_mark
=
'\0'
;
char
*
sp_path
=
path
;
char
*
rd_path
=
split_mark
+
1
;
struct
sp_entry_info
*
sp
;
if
(
sp_info_head
==
NULL
)
{
sp_info_head
=
xzalloc
(
sizeof
(
struct
sp_entry_info
),
"Failed to allocate sp_entry_info struct"
);
sp
=
sp_info_head
;
}
else
{
sp
=
sp_info_head
;
while
(
sp
->
next
!=
NULL
)
{
sp
=
sp
->
next
;
}
sp
->
next
=
xzalloc
(
sizeof
(
struct
sp_entry_info
),
"Failed to allocate sp_entry_info struct"
);
char
*
pm_path
=
split_mark
+
1
;
sp
=
sp
->
next
;
}
sp
_pkg
=
xzalloc
(
sizeof
(
struct
sp_pkg_info
),
"Failed to allocate sp_pkg_info struct"
);
load_file
(
s
p_path
,
&
sp
->
sp
_data
,
&
sp
->
sp
_size
);
printf
(
"Loaded
image
file %s (%
l
u bytes)
\n
"
,
s
p_path
,
sp
->
sp
_size
);
load_file
(
p
m
_path
,
&
sp
_pkg
->
pm
_data
,
&
sp
_pkg
->
pm
_size
);
printf
(
"
\n
Loaded
SP Manifest
file %s (%u bytes)
\n
"
,
p
m
_path
,
sp
_pkg
->
pm
_size
);
load_file
(
rd
_path
,
&
sp
->
rd
_data
,
&
sp
->
rd
_size
);
printf
(
"Loaded
RD
file %s (%
l
u bytes)
\n
"
,
rd
_path
,
sp
->
rd
_size
);
load_file
(
sp
_path
,
&
sp
_pkg
->
img
_data
,
&
sp
_pkg
->
img
_size
);
printf
(
"Loaded
SP Image
file %s (%u bytes)
\n
"
,
sp
_path
,
sp
_pkg
->
img
_size
);
sp_
c
ou
nt
++
;
*
sp_ou
t
=
sp_pkg
;
}
static
void
output_write
(
const
char
*
path
)
/*
* Write SP package data structure into output file.
*/
static
void
output_write
(
const
char
*
path
,
struct
sp_pkg_info
*
sp
,
bool
header
)
{
struct
sp_entry_info
*
sp
;
if
(
sp_count
==
0
)
{
fprintf
(
stderr
,
"error: At least one SP must be provided.
\n
"
);
exit
(
1
);
}
/* The layout of the structs is specified in the header file sptool.h */
printf
(
"Writing %lu partitions to output file.
\n
"
,
sp_count
);
unsigned
int
header_size
=
(
sizeof
(
struct
sp_pkg_header
)
*
8
)
+
(
sizeof
(
struct
sp_pkg_entry
)
*
8
*
sp_count
);
struct
sp_pkg_header
sp_header_info
;
unsigned
int
file_ptr
=
0
;
FILE
*
f
=
fopen
(
path
,
"wb"
);
if
(
f
==
NULL
)
{
...
...
@@ -207,70 +225,46 @@ static void output_write(const char *path)
exit
(
1
);
}
unsigned
int
file_ptr
=
align_to
(
header_size
,
PAGE_SIZE
);
/* First, save all partition images aligned to page boundaries */
sp
=
sp_info_head
;
for
(
uint64_t
i
=
0
;
i
<
sp_count
;
i
++
)
{
xfseek
(
f
,
file_ptr
,
SEEK_SET
);
printf
(
"Writing image %lu to offset 0x%x (0x%lx bytes)
\n
"
,
i
,
file_ptr
,
sp
->
sp_size
);
sp
->
sp_offset
=
file_ptr
;
xfwrite
(
sp
->
sp_data
,
sp
->
sp_size
,
f
);
file_ptr
=
align_to
(
file_ptr
+
sp
->
sp_size
,
PAGE_SIZE
);
sp
=
sp
->
next
;
/* Reserve Header size */
if
(
header
)
{
file_ptr
=
sizeof
(
struct
sp_pkg_header
);
}
/* Now, save resource description blobs aligned to 8 bytes */
/* Save partition manifest */
xfseek
(
f
,
file_ptr
,
SEEK_SET
);
printf
(
"Writing SP Manifest at offset 0x%x (%u bytes)
\n
"
,
file_ptr
,
sp
->
pm_size
);
sp
=
sp_info_head
;
for
(
uint64_t
i
=
0
;
i
<
sp_count
;
i
++
)
{
xfseek
(
f
,
file_ptr
,
SEEK_SET
);
printf
(
"Writing RD blob %lu to offset 0x%x (0x%lx bytes)
\n
"
,
i
,
file_ptr
,
sp
->
rd_size
);
sp
->
rd_offset
=
file_ptr
;
xfwrite
(
sp
->
rd_data
,
sp
->
rd_size
,
f
);
file_ptr
=
align_to
(
file_ptr
+
sp
->
rd_size
,
8
);
sp
=
sp
->
next
;
}
sp
->
pm_offset
=
file_ptr
;
xfwrite
(
sp
->
pm_data
,
sp
->
pm_size
,
f
);
/* Finally, write header */
/* Save partition image aligned to Page size */
file_ptr
=
align_to
((
sp
->
pm_offset
+
sp
->
pm_size
),
PAGE_SIZE
);
xfseek
(
f
,
file_ptr
,
SEEK_SET
);
printf
(
"Writing SP Image at offset 0x%x (%u bytes)
\n
"
,
file_ptr
,
sp
->
img_size
);
uint64_t
version
=
0x1
;
uint64_t
sp_num
=
sp_count
;
sp
->
img_offset
=
file_ptr
;
xfwrite
(
sp
->
img_data
,
sp
->
img_size
,
f
)
;
xfseek
(
f
,
0
,
SEEK_SET
);
/* Finally, write header, if needed */
if
(
header
)
{
sp_header_info
.
magic
=
SECURE_PARTITION_MAGIC
;
sp_header_info
.
version
=
0x1
;
sp_header_info
.
img_offset
=
sp
->
img_offset
;
sp_header_info
.
img_size
=
sp
->
img_size
;
sp_header_info
.
pm_offset
=
sp
->
pm_offset
;
sp_header_info
.
pm_size
=
sp
->
pm_size
;
xfwrite
(
&
version
,
sizeof
(
uint64_t
),
f
);
xfwrite
(
&
sp_num
,
sizeof
(
uint64_t
),
f
);
xfseek
(
f
,
0
,
SEEK_SET
);
sp
=
sp_info_head
;
printf
(
"Writing package header
\n
"
)
;
for
(
unsigned
int
i
=
0
;
i
<
sp_count
;
i
++
)
{
uint64_t
sp_offset
,
sp_size
,
rd_offset
,
rd_size
;
sp_offset
=
sp
->
sp_offset
;
sp_size
=
align_to
(
sp
->
sp_size
,
PAGE_SIZE
);
rd_offset
=
sp
->
rd_offset
;
rd_size
=
sp
->
rd_size
;
xfwrite
(
&
sp_offset
,
sizeof
(
uint64_t
),
f
);
xfwrite
(
&
sp_size
,
sizeof
(
uint64_t
),
f
);
xfwrite
(
&
rd_offset
,
sizeof
(
uint64_t
),
f
);
xfwrite
(
&
rd_size
,
sizeof
(
uint64_t
),
f
);
sp
=
sp
->
next
;
xfwrite
(
&
sp_header_info
,
sizeof
(
struct
sp_pkg_header
),
f
);
}
/* All information has been written now */
printf
(
"
\n
sptool: Built Secure Partition blob %s
\n
"
,
path
);
fclose
(
f
);
}
...
...
@@ -286,30 +280,51 @@ static void usage(void)
#endif
printf
(
" [<args>]
\n\n
"
);
printf
(
"This tool takes as inputs several image binary files and the
\n
"
"resource description blobs as input and generates a package
\n
"
"file that contains them.
\n\n
"
);
printf
(
"This tool takes as input set of image binary files and the
\n
"
"partition manifest blobs as input and generates set of
\n
"
"output package files
\n
"
"Usage example: sptool -i sp1.bin:sp1.dtb -o sp1.pkg
\n
"
" -i sp2.bin:sp2.dtb -o sp2.pkg ...
\n\n
"
);
printf
(
"Commands supported:
\n
"
);
printf
(
" -o <path> Set output file path.
\n
"
);
printf
(
" -i <sp_path:
rd
_path> Add Secure Partition image and
Resource
\n
"
"
Description
blob (specified in two paths
\n
"
printf
(
" -i <sp_path:
pm
_path> Add Secure Partition image and
\n
"
"
Manifest
blob (specified in two paths
\n
"
" separated by a colon).
\n
"
);
printf
(
" -n Generate package without header
\n
"
);
printf
(
" -h Show this message.
\n
"
);
exit
(
1
);
}
int
main
(
int
argc
,
char
*
argv
[])
{
struct
sp_pkg_info
*
sp_pkg
=
NULL
;
struct
arg_list
*
in_head
=
NULL
;
struct
arg_list
*
out_head
=
NULL
;
struct
arg_list
*
in_list
=
NULL
;
struct
arg_list
*
out_list
=
NULL
;
unsigned
int
match_counter
=
0
;
bool
need_header
=
true
;
int
ch
;
const
char
*
outname
=
NULL
;
while
((
ch
=
getopt
(
argc
,
argv
,
"hi:o:"
))
!=
-
1
)
{
if
(
argc
<=
1
)
{
fprintf
(
stderr
,
"error: File paths must be provided.
\n\n
"
);
usage
();
return
1
;
}
while
((
ch
=
getopt
(
argc
,
argv
,
"hni:o:"
))
!=
-
1
)
{
switch
(
ch
)
{
case
'i'
:
load_sp_rd
(
optarg
);
append_user_input
(
&
in_head
,
optarg
);
match_counter
++
;
break
;
case
'o'
:
outname
=
optarg
;
append_user_input
(
&
out_head
,
optarg
);
match_counter
--
;
break
;
case
'n'
:
need_header
=
false
;
break
;
case
'h'
:
default:
...
...
@@ -317,18 +332,29 @@ int main(int argc, char *argv[])
}
}
argc
-=
optind
;
argv
+=
optind
;
if
(
outname
==
NULL
)
{
fprintf
(
stderr
,
"error: An output file path must be provided.
\n\n
"
);
if
(
match_counter
)
{
fprintf
(
stderr
,
"error: Input/Output count mismatch.
\n\n
"
);
freelist
(
in_head
);
freelist
(
out_head
);
usage
();
return
1
;
}
output_write
(
outname
);
in_list
=
in_head
;
out_list
=
out_head
;
while
(
in_list
!=
NULL
)
{
load_sp_pm
(
in_list
->
usr_input
,
&
sp_pkg
);
output_write
(
out_list
->
usr_input
,
sp_pkg
,
need_header
);
in_list
=
in_list
->
next
;
out_list
=
out_list
->
next
;
}
argc
-=
optind
;
argv
+=
optind
;
cleanup
();
cleanup
(
sp_pkg
);
freelist
(
in_head
);
freelist
(
out_head
);
return
0
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment