X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=lib%2Fverity%2Fverity_fec.c;h=2dbf59e85190aa52a260261d9a5a95c255e1b2a5;hb=420ad62f0bb77970a6ba234bde9e1405f7df7789;hp=e076c970f78b552279b3fc746d904cc7ce61291d;hpb=f7fc3bb4e50cce23dd95111b246b6e034537e2cf;p=platform%2Fupstream%2Fcryptsetup.git diff --git a/lib/verity/verity_fec.c b/lib/verity/verity_fec.c index e076c97..2dbf59e 100644 --- a/lib/verity/verity_fec.c +++ b/lib/verity/verity_fec.c @@ -2,7 +2,7 @@ * dm-verity Forward Error Correction (FEC) support * * Copyright (C) 2015 Google, Inc. All rights reserved. - * Copyright (C) 2017-2021 Red Hat, Inc. All rights reserved. + * Copyright (C) 2017-2023 Red Hat, Inc. All rights reserved. * * This file is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -178,6 +178,7 @@ static int FEC_process_inputs(struct crypt_device *cd, r = decode_rs_char(rs, rs_block); if (r < 0) { log_err(cd, _("Failed to repair parity for block %" PRIu64 "."), n); + r = -EPERM; goto out; } /* return number of detected errors */ @@ -201,6 +202,22 @@ out: return r; } +static int VERITY_FEC_validate(struct crypt_device *cd, struct crypt_params_verity *params) +{ + if (params->data_block_size != params->hash_block_size) { + log_err(cd, _("Block sizes must match for FEC.")); + return -EINVAL; + } + + if (params->fec_roots > FEC_RSM - FEC_MIN_RSN || + params->fec_roots < FEC_RSM - FEC_MAX_RSN) { + log_err(cd, _("Invalid number of parity bytes.")); + return -EINVAL; + } + + return 0; +} + int VERITY_FEC_process(struct crypt_device *cd, struct crypt_params_verity *params, struct device *fec_device, int check_fec, @@ -223,16 +240,9 @@ int VERITY_FEC_process(struct crypt_device *cd, }; /* validate parameters */ - if (params->data_block_size != params->hash_block_size) { - log_err(cd, _("Block sizes must match for FEC.")); - return -EINVAL; - } - - if (params->fec_roots > FEC_RSM - FEC_MIN_RSN || - params->fec_roots < FEC_RSM - FEC_MAX_RSN) { - log_err(cd, _("Invalid number of parity bytes.")); - return -EINVAL; - } + r = VERITY_FEC_validate(cd, params); + if (r < 0) + return r; if (!inputs[0].count) { log_err(cd, _("Invalid FEC segment length.")); @@ -280,12 +290,16 @@ out: return r; } +/* All blocks that are covered by FEC */ uint64_t VERITY_FEC_blocks(struct crypt_device *cd, struct device *fec_device, struct crypt_params_verity *params) { uint64_t blocks = 0; + if (!fec_device || VERITY_FEC_validate(cd, params) < 0) + return 0; + /* * FEC covers this data: * | protected data | hash area | padding (optional foreign metadata) | @@ -314,3 +328,9 @@ uint64_t VERITY_FEC_blocks(struct crypt_device *cd, return blocks; } + +/* Blocks needed to store FEC data, blocks must be validated/calculated by VERITY_FEC_blocks() */ +uint64_t VERITY_FEC_RS_blocks(uint64_t blocks, uint32_t roots) +{ + return FEC_div_round_up(blocks, FEC_RSM - roots) * roots; +}