diff --git a/lib/internal.h b/lib/internal.h index 91f16231..9560c2d7 100644 --- a/lib/internal.h +++ b/lib/internal.h @@ -46,6 +46,7 @@ /* to silent gcc -Wcast-qual for const cast */ #define CONST_CAST(x) (x)(uintptr_t) +#define SHIFT_4K 12 #define SECTOR_SHIFT 9 #define SECTOR_SIZE (1 << SECTOR_SHIFT) #define MAX_SECTOR_SIZE 4096 /* min page size among all platforms */ @@ -55,6 +56,11 @@ #define at_least(a, b) ({ __typeof__(a) __at_least = (a); (__at_least >= (b))?__at_least:(b); }) +#define MISALIGNED(a, b) ((a) & ((b) - 1)) +#define MISALIGNED_4K(a) MISALIGNED((a), 1 << SHIFT_4K) +#define MISALIGNED_512(a) MISALIGNED((a), 1 << SECTOR_SHIFT) +#define NOTPOW2(a) MISALIGNED((a), (a)) + #ifndef ARRAY_SIZE # define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) #endif diff --git a/lib/luks1/keyencryption.c b/lib/luks1/keyencryption.c index a19ab34c..a3a7f48b 100644 --- a/lib/luks1/keyencryption.c +++ b/lib/luks1/keyencryption.c @@ -150,7 +150,7 @@ int LUKS_encrypt_to_storage(char *src, size_t srcLength, int devfd = -1, r = 0; /* Only whole sector writes supported */ - if (srcLength % SECTOR_SIZE) + if (MISALIGNED_512(srcLength)) return -EINVAL; /* Encrypt buffer */ @@ -215,7 +215,7 @@ int LUKS_decrypt_from_storage(char *dst, size_t dstLength, int devfd = -1, r = 0; /* Only whole sector reads supported */ - if (dstLength % SECTOR_SIZE) + if (MISALIGNED_512(dstLength)) return -EINVAL; r = crypt_storage_init(&s, 0, cipher, cipher_mode, vk->key, vk->keylength); diff --git a/lib/luks2/luks2_json_metadata.c b/lib/luks2/luks2_json_metadata.c index b4d1967c..abfa74ef 100644 --- a/lib/luks2/luks2_json_metadata.c +++ b/lib/luks2/luks2_json_metadata.c @@ -535,14 +535,16 @@ static int hdr_validate_crypt_segment(json_object *jobj, const char *key, json_o } sector_size = json_object_get_uint32(jobj_sector_size); - if (!sector_size || sector_size % SECTOR_SIZE) { + if (!sector_size || MISALIGNED_512(sector_size)) { log_dbg("Illegal sector size: %" PRIu32, sector_size); return 1; } if (!numbered("iv_tweak", json_object_get_string(jobj_ivoffset)) || - !json_str_to_uint64(jobj_ivoffset, &ivoffset)) + !json_str_to_uint64(jobj_ivoffset, &ivoffset)) { + log_dbg("Illegal iv_tweak value."); return 1; + } if (size % sector_size) { log_dbg("Size field has to be aligned to sector size: %" PRIu32, sector_size); @@ -594,11 +596,11 @@ static int hdr_validate_segments(json_object *hdr_jobj) size = 0; /* all device-mapper devices are aligned to 512 sector size */ - if (offset % SECTOR_SIZE) { + if (MISALIGNED_512(offset)) { log_dbg("Offset field has to be aligned to sector size: %" PRIu32, SECTOR_SIZE); return 1; } - if (size % SECTOR_SIZE) { + if (MISALIGNED_512(size)) { log_dbg("Size field has to be aligned to sector size: %" PRIu32, SECTOR_SIZE); return 1; } @@ -722,7 +724,7 @@ static int validate_keyslots_size(json_object *hdr_jobj, json_object *jobj_keysl if (!json_str_to_uint64(jobj_keyslots_size, &keyslots_size)) return 1; - if (keyslots_size % 4096) { + if (MISALIGNED_4K(keyslots_size)) { log_dbg("keyslots_size is not 4 KiB aligned"); return 1; } @@ -779,7 +781,7 @@ static int hdr_validate_config(json_object *hdr_jobj) return 1; } - if (json_size % 4096) { + if (MISALIGNED_4K(json_size)) { log_dbg("Json area is not properly aligned to 4 KiB."); return 1; } diff --git a/lib/luks2/luks2_keyslot_luks2.c b/lib/luks2/luks2_keyslot_luks2.c index 5e1d348b..2aa46b14 100644 --- a/lib/luks2/luks2_keyslot_luks2.c +++ b/lib/luks2/luks2_keyslot_luks2.c @@ -48,7 +48,7 @@ static int luks2_encrypt_to_storage(char *src, size_t srcLength, int devfd = -1, r; /* Only whole sector writes supported */ - if (srcLength % SECTOR_SIZE) + if (MISALIGNED_512(srcLength)) return -EINVAL; /* Encrypt buffer */ @@ -113,7 +113,7 @@ static int luks2_decrypt_from_storage(char *dst, size_t dstLength, int devfd = -1, r; /* Only whole sector writes supported */ - if (dstLength % SECTOR_SIZE) + if (MISALIGNED_512(dstLength)) return -EINVAL; r = crypt_storage_init(&s, 0, cipher, cipher_mode, vk->key, vk->keylength); diff --git a/lib/setup.c b/lib/setup.c index f91de309..67a08b69 100644 --- a/lib/setup.c +++ b/lib/setup.c @@ -1366,7 +1366,7 @@ static int _crypt_format_plain(struct crypt_device *cd, sector_size = SECTOR_SIZE; if (sector_size < SECTOR_SIZE || sector_size > MAX_SECTOR_SIZE || - (sector_size & (sector_size - 1))) { + NOTPOW2(sector_size)) { log_err(cd, _("Unsupported encryption sector size.")); return -EINVAL; } @@ -1510,7 +1510,7 @@ static int _crypt_format_luks2(struct crypt_device *cd, } if (sector_size < SECTOR_SIZE || sector_size > MAX_SECTOR_SIZE || - (sector_size & (sector_size - 1))) { + NOTPOW2(sector_size)) { log_err(cd, _("Unsupported encryption sector size.")); return -EINVAL; } @@ -1734,12 +1734,12 @@ static int _crypt_format_verity(struct crypt_device *cd, return -EINVAL; } - if (params->hash_area_offset % 512) { + if (MISALIGNED_512(params->hash_area_offset)) { log_err(cd, _("Unsupported VERITY hash offset.")); return -EINVAL; } - if (params->fec_area_offset % 512) { + if (MISALIGNED_512(params->fec_area_offset)) { log_err(cd, _("Unsupported VERITY FEC offset.")); return -EINVAL; } @@ -2106,7 +2106,7 @@ int crypt_resize(struct crypt_device *cd, const char *name, uint64_t new_size) if (r) goto out; - if (new_size & ((dmd.u.crypt.sector_size >> SECTOR_SHIFT) - 1)) { + if (MISALIGNED(new_size, dmd.u.crypt.sector_size >> SECTOR_SHIFT)) { log_err(cd, _("Device %s size is not aligned to requested sector size (%u bytes)."), crypt_get_device_name(cd), (unsigned)dmd.u.crypt.sector_size); r = -EINVAL; diff --git a/lib/utils_wipe.c b/lib/utils_wipe.c index d0a6f6d7..77550c76 100644 --- a/lib/utils_wipe.c +++ b/lib/utils_wipe.c @@ -153,7 +153,7 @@ int crypt_wipe_device(struct crypt_device *cd, /* FIXME: if wipe_block_size < bsize, then a wipe is highly ineffective */ /* Everything must be aligned to SECTOR_SIZE */ - if ((offset % SECTOR_SIZE) || (length % SECTOR_SIZE) || (wipe_block_size % SECTOR_SIZE)) + if (MISALIGNED_512(offset) || MISALIGNED_512(length) || MISALIGNED_512(wipe_block_size)) return -EINVAL; devfd = device_open(device, O_RDWR); diff --git a/lib/verity/verity.c b/lib/verity/verity.c index db682bda..a8e62974 100644 --- a/lib/verity/verity.c +++ b/lib/verity/verity.c @@ -71,7 +71,7 @@ int VERITY_read_sb(struct crypt_device *cd, return -EINVAL; } - if (sb_offset % 512) { + if (MISALIGNED_512(sb_offset)) { log_err(cd, _("Unsupported VERITY hash offset.")); return -EINVAL; }