@@ -369,7 +369,7 @@ static int zstd_step(void* state, void* buffer, size_t size)
int copyfile(int fdin, void *out, unsigned int nbytes, unsigned long *offs, unsigned long long seek,
int skip_file, int __attribute__ ((__unused__)) compressed,
- uint32_t *checksum, unsigned char *hash, int encrypted, writeimage callback)
+ uint32_t *checksum, unsigned char *hash, int encrypted, const char *imgivt, writeimage callback)
{
unsigned int percent, prevpercent = 0;
int ret = 0;
@@ -381,6 +381,7 @@ int copyfile(int fdin, void *out, unsigned int nbytes, unsigned long *offs, unsi
unsigned int md_len = 0;
unsigned char *aes_key = NULL;
unsigned char *ivt = NULL;
+ unsigned char ivtbuf[32];
struct InputState input_state = {
.fdin = fdin,
@@ -440,7 +441,10 @@ int copyfile(int fdin, void *out, unsigned int nbytes, unsigned long *offs, unsi
if (encrypted) {
aes_key = get_aes_key();
- ivt = get_aes_ivt();
+ if (imgivt && strlen(imgivt) && !ascii_to_bin(ivtbuf, imgivt, sizeof(ivtbuf))) {
+ ivt = ivtbuf;
+ } else
+ ivt = get_aes_ivt();
decrypt_state.dcrypt = swupdate_DECRYPT_init(aes_key, ivt);
if (!decrypt_state.dcrypt) {
ERROR("decrypt initialization failure, aborting");
@@ -622,6 +626,7 @@ int copyimage(void *out, struct img_type *img, writeimage callback)
&img->checksum,
img->sha256,
img->is_encrypted,
+ img->ivt_ascii,
callback);
}
@@ -686,7 +691,7 @@ int extract_sw_description(int fd, const char *descfile, off_t *offs)
close(fdout);
return -1;
}
- if (copyfile(fd, &fdout, fdh.size, &offset, 0, 0, 0, &checksum, NULL, 0, NULL) < 0) {
+ if (copyfile(fd, &fdout, fdh.size, &offset, 0, 0, 0, &checksum, NULL, 0, NULL, NULL) < 0) {
ERROR("%s corrupted or not valid", descfile);
close(fdout);
return -1;
@@ -732,7 +737,7 @@ int extract_img_from_cpio(int fd, unsigned long offset, struct filehdr *fdh)
}
off_t extract_next_file(int fd, int fdout, off_t start, int compressed,
- int encrypted, unsigned char *hash)
+ int encrypted, char *ivt, unsigned char *hash)
{
int ret;
struct filehdr fdh;
@@ -758,7 +763,7 @@ off_t extract_next_file(int fd, int fdout, off_t start, int compressed,
return ret;
}
- ret = copyfile(fd, &fdout, fdh.size, &offset, 0, 0, compressed, &checksum, hash, encrypted, NULL);
+ ret = copyfile(fd, &fdout, fdh.size, &offset, 0, 0, compressed, &checksum, hash, encrypted, ivt, NULL);
if (ret < 0) {
ERROR("Error copying extracted file");
return ret;
@@ -811,7 +816,7 @@ int cpio_scan(int fd, struct swupdate_cfg *cfg, off_t start)
* we do not have to provide fdout
*/
if (copyfile(fd, NULL, fdh.size, &offset, 0, 1, 0, &checksum, img ? img->sha256 : NULL,
- 0, NULL) != 0) {
+ 0, NULL, NULL) != 0) {
ERROR("invalid archive");
return -1;
}
@@ -120,7 +120,7 @@ static int extract_scripts(int fd, struct imglist *head, int fromfile)
if (fromfile)
ret = extract_next_file(fd, fdout, script->offset, 0,
- script->is_encrypted, script->sha256);
+ script->is_encrypted, script->ivt_ascii, script->sha256);
else {
int fdin;
char *tmpfile;
@@ -147,6 +147,7 @@ static int extract_scripts(int fd, struct imglist *head, int fromfile)
&checksum,
script->sha256,
script->is_encrypted,
+ script->ivt_ascii,
NULL);
close(fdin);
}
@@ -99,7 +99,7 @@ static int extract_file_to_tmp(int fd, const char *fname, unsigned long *poffs)
if (fdout < 0)
return -1;
- if (copyfile(fd, &fdout, fdh.size, poffs, 0, 0, 0, &checksum, NULL, 0, NULL) < 0) {
+ if (copyfile(fd, &fdout, fdh.size, poffs, 0, 0, 0, &checksum, NULL, 0, NULL, NULL) < 0) {
close(fdout);
return -1;
}
@@ -213,7 +213,7 @@ static int extract_files(int fd, struct swupdate_cfg *software)
fdout = openfileoutput(img->extract_file);
if (fdout < 0)
return -1;
- if (copyfile(fd, &fdout, fdh.size, &offset, 0, 0, 0, &checksum, img->sha256, 0, NULL) < 0) {
+ if (copyfile(fd, &fdout, fdh.size, &offset, 0, 0, 0, &checksum, img->sha256, 0, NULL, NULL) < 0) {
close(fdout);
return -1;
}
@@ -227,7 +227,7 @@ static int extract_files(int fd, struct swupdate_cfg *software)
break;
case SKIP_FILE:
- if (copyfile(fd, &fdout, fdh.size, &offset, 0, skip, 0, &checksum, NULL, 0, NULL) < 0) {
+ if (copyfile(fd, &fdout, fdh.size, &offset, 0, skip, 0, &checksum, NULL, 0, NULL, NULL) < 0) {
return -1;
}
if (checksum != (unsigned long)fdh.chksum) {
@@ -292,6 +292,9 @@ static void lua_string_to_img(struct img_type *img, const char *key,
sizeof(img->filesystem));
if (!strcmp(key, "sha256"))
ascii_to_hash(img->sha256, value);
+ if (!strcmp(key, "ivt"))
+ strncpy(img->ivt_ascii, value,
+ sizeof(img->ivt_ascii));
if (!strncmp(key, offset, sizeof(offset))) {
strncpy(seek_str, value,
@@ -364,6 +367,7 @@ static int l_copy2file(lua_State *L)
&checksum,
img.sha256,
img.is_encrypted,
+ img.ivt_ascii,
NULL);
update_table(L, &img);
lua_pop(L, 1);
@@ -435,6 +439,7 @@ static int l_istream_read(lua_State* L)
&checksum,
img.sha256,
img.is_encrypted,
+ img.ivt_ascii,
istream_read_callback);
lua_pop(L, 1);
@@ -475,6 +480,7 @@ static void update_table(lua_State* L, struct img_type *img)
LUA_PUSH_IMG_STRING(img, "mtdname", path);
LUA_PUSH_IMG_STRING(img, "data", type_data);
LUA_PUSH_IMG_STRING(img, "filesystem", filesystem);
+ LUA_PUSH_IMG_STRING(img, "ivt", ivt_ascii);
LUA_PUSH_IMG_BOOL(img, "installed_directly", install_directly);
LUA_PUSH_IMG_BOOL(img, "install_if_different", id.install_if_different);
@@ -1292,6 +1292,13 @@ There are 4 main sections inside sw-description:
| | | scripts | and must be decrypted before |
| | | | installing. |
+-------------+----------+------------+---------------------------------------+
+ | ivt | string | images | IVT in case of encrypted artefact |
+ | | | files | It has no value if "encrypted" is not |
+ | | | scripts | set. Each artefact can have an own |
+ | | | | IVT to avoid attacker can guess the |
+ | | | | the key. |
+ | | | | It is a ASCII string of 32 chars |
+ +-------------+----------+------------+---------------------------------------+
| data | string | images | This is used to pass arbitrary data |
| | | files | to a handler. |
| | | scripts | |
@@ -182,6 +182,7 @@ static int copy_raw_image(struct img_type *img,
&checksum,
0, /* no sha256 */
0, /* no encrypted */
+ NULL, /* no IVT */
NULL);
close(fdout);
@@ -348,6 +348,7 @@ static int apply_rdiff_patch(struct img_type *img,
&img->checksum,
img->sha256,
img->is_encrypted,
+ img->ivt_ascii,
apply_rdiff_chunk_cb);
if (ret != 0) {
ERROR("Error %d running rdiff job, aborting.", ret);
@@ -107,6 +107,7 @@ static int readback_postinst(struct img_type *img)
NULL, /* no checksum */
hash,
0, /* no encrypted */
+ NULL, /* no IVT */
NULL); /* no callback */
if (status == 0) {
INFO("Readback verification success");
@@ -74,6 +74,7 @@ struct img_type {
int compressed;
int preserve_attributes; /* whether to preserve attributes in archives */
int is_encrypted;
+ char ivt_ascii[32];
int install_directly;
int is_script;
int is_partitioner;
@@ -176,7 +176,7 @@ int copyfile(int fdin, void *out, unsigned int nbytes, unsigned long *offs,
int copyimage(void *out, struct img_type *img, writeimage callback);
int extract_sw_description(int fd, const char *descfile, off_t *offs);
off_t extract_next_file(int fd, int fdout, off_t start, int compressed,
- int encrypted, unsigned char *hash);
+ int encrypted, char *ivt, unsigned char *hash);
int openfileoutput(const char *filename);
int mkpath(char *dir, mode_t mode);
int swupdate_file_setnonblock(int fd, bool block);
@@ -308,6 +308,7 @@ static int parse_common_attributes(parsertype p, void *elem, struct img_type *im
get_field(p, elem, "install-if-different", &image->id.install_if_different);
get_field(p, elem, "install-if-higher", &image->id.install_if_higher);
get_field(p, elem, "encrypted", &image->is_encrypted);
+ GET_FIELD_STRING(p, elem, "ivt", image->ivt_ascii);
return 0;
}
Reusing the same Initialization Vector (IV) is considered bad practise and must be avoided. SWUpdate has a global AES key and IV to decrypt artefact. Change this and add a new attribute ("ivt") that can be specific for each artefact. Signed-off-by: Stefano Babic <sbabic@denx.de> --- core/cpio_utils.c | 17 +++++++++++------ core/installer.c | 3 ++- core/stream_interface.c | 6 +++--- corelib/lua_interface.c | 6 ++++++ doc/source/sw-description.rst | 7 +++++++ handlers/raw_handler.c | 1 + handlers/rdiff_handler.c | 1 + handlers/readback_handler.c | 1 + include/swupdate.h | 1 + include/util.h | 2 +- parser/parser.c | 1 + 11 files changed, 35 insertions(+), 11 deletions(-)