bool image_ecc_save(image *ctx)
{
- assert(sizeof(fec_header) <= FEC_BLOCKSIZE);
-
- uint8_t header[FEC_BLOCKSIZE];
- uint8_t *p = header;
+ assert(2 * sizeof(fec_header) <= FEC_BLOCKSIZE);
- memset(p, 0, FEC_BLOCKSIZE);
+ uint8_t header[FEC_BLOCKSIZE] = {0};
- fec_header *f = (fec_header *)p;
+ fec_header *f = (fec_header *)header;
f->magic = FEC_MAGIC;
f->version = FEC_VERSION;
SHA256(ctx->fec, ctx->fec_size, f->hash);
/* store a copy of the fec_header at the end of the header block */
- memcpy(&p[sizeof(header) - sizeof(fec_header)], p, sizeof(fec_header));
+ memcpy(&header[sizeof(header) - sizeof(fec_header)], header,
+ sizeof(fec_header));
assert(ctx->fec_filename);
strerror(errno));
}
- if (!android::base::WriteFully(fd, ctx->fec, ctx->fec_size) ||
- !android::base::WriteFully(fd, header, sizeof(header))) {
+ if (!android::base::WriteFully(fd, ctx->fec, ctx->fec_size)) {
FATAL("failed to write to output: %s\n", strerror(errno));
}
+ if (ctx->padding > 0) {
+ uint8_t padding[FEC_BLOCKSIZE] = {0};
+
+ for (uint32_t i = 0; i < ctx->padding; i += FEC_BLOCKSIZE) {
+ if (!android::base::WriteFully(fd, padding, FEC_BLOCKSIZE)) {
+ FATAL("failed to write padding: %s\n", strerror(errno));
+ }
+ }
+ }
+
+ if (!android::base::WriteFully(fd, header, sizeof(header))) {
+ FATAL("failed to write to header: %s\n", strerror(errno));
+ }
+
close(fd);
return true;
" -r, --roots=<bytes> number of parity bytes\n"
" -j, --threads=<threads> number of threads to use\n"
" -S treat data as a sparse file\n"
+ "encoding options:\n"
+ " -p, --padding=<bytes> add padding after ECC data\n"
"decoding options:\n"
" -i, --inplace correct <data> in place\n"
);
"files\n");
}
+ if (ctx.padding) {
+ FATAL("invalid parameters: padding is only relevant when encoding\n");
+ }
+
if (!image_ecc_load(fec_filename, &ctx) ||
!image_load(inp_filenames, &ctx)) {
FATAL("failed to read input\n");
{"print-fec-size", required_argument, 0, 's'},
{"get-ecc-start", required_argument, 0, 'E'},
{"get-verity-start", required_argument, 0, 'V'},
+ {"padding", required_argument, 0, 'p'},
{"verbose", no_argument, 0, 'v'},
{NULL, 0, 0, 0}
};
- int c = getopt_long(argc, argv, "hedSr:imj:s:E:V:v", long_options, NULL);
+ int c = getopt_long(argc, argv, "hedSr:ij:s:E:V:p:v", long_options, NULL);
if (c < 0) {
break;
}
mode = MODE_GETVERITYSTART;
inp_filenames.push_back(optarg);
break;
+ case 'p':
+ ctx.padding = (uint32_t)parse_arg(optarg, "padding", UINT32_MAX);
+ if (ctx.padding % FEC_BLOCKSIZE) {
+ FATAL("padding must be multiple of %u\n", FEC_BLOCKSIZE);
+ }
+ break;
case 'v':
ctx.verbose = true;
break;