From ee7edfea4d0bd7f5242b974d28a586dcd70c72a2 Mon Sep 17 00:00:00 2001 From: Shreyas K K Date: Wed, 29 Mar 2023 13:21:04 +0530 Subject: [PATCH] soc: qcom_secure_hibernation: Use sequential IV for decryption Using the same IV for the decryption is a security concern. Use sequential IV for decryption of the pages. Change-Id: I358f40970d496e877febc97abb445ba3b9b47603 Signed-off-by: Shreyas K K --- drivers/soc/qcom/qcom_secure_hibernation.c | 25 +++++++++++++++++++--- include/soc/qcom/qcom_hibernation.h | 5 +++-- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/drivers/soc/qcom/qcom_secure_hibernation.c b/drivers/soc/qcom/qcom_secure_hibernation.c index 83be7e9bbd02..cc08384a1452 100644 --- a/drivers/soc/qcom/qcom_secure_hibernation.c +++ b/drivers/soc/qcom/qcom_secure_hibernation.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -84,6 +84,7 @@ static uint8_t *authslot_start; static unsigned short root_swap_dev; static struct work_struct save_params_work; static struct completion write_done; +static unsigned char iv[IV_SIZE]; static void init_sg(struct scatterlist *sg, void *data, unsigned int size) { @@ -104,6 +105,21 @@ static void skip_swap_map_write(void *data, bool *skip) *skip = true; } +static void increment_iv(unsigned char *iv, u8 size) +{ + int i; + u16 num, carry = 1; + + i = size - 1; + do { + num = (u8)iv[i]; + num += carry; + iv[i] = num & 0xFF; + carry = (num > 0xFF) ? 1 : 0; + i--; + } while (i >= 0 && carry != 0); +} + static void encrypt_page(void *data, void *buf) { struct scatterlist sg_in[2], sg_out[2]; @@ -123,8 +139,10 @@ static void encrypt_page(void *data, void *buf) ret = crypto_aead_setauthsize(tfm, AUTH_SIZE); iv_size = crypto_aead_ivsize(tfm); - if (iv_size && first_encrypt) + if (iv_size && first_encrypt) { get_random_bytes(params->iv, iv_size); + memcpy((void *)iv, params->iv, IV_SIZE); + } ret = crypto_aead_setkey(tfm, key, AES256_KEY_SIZE); if (ret) { @@ -138,7 +156,8 @@ static void encrypt_page(void *data, void *buf) init_sg(sg_out, temp_out_buf, PAGE_SIZE + AUTH_SIZE); aead_request_set_ad(req, sizeof(params->aad)); - aead_request_set_crypt(req, sg_in, sg_out, PAGE_SIZE, params->iv); + increment_iv(iv, IV_SIZE); + aead_request_set_crypt(req, sg_in, sg_out, PAGE_SIZE, iv); crypto_aead_encrypt(req); ret = crypto_wait_req(ret, &wait); if (ret) { diff --git a/include/soc/qcom/qcom_hibernation.h b/include/soc/qcom/qcom_hibernation.h index 9adf9600b0db..9fe0c346ab78 100644 --- a/include/soc/qcom/qcom_hibernation.h +++ b/include/soc/qcom/qcom_hibernation.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef __SOC_QCOM_HIBERNATION_H__ @@ -23,12 +23,13 @@ #define WRAPPED_KEY_SIZE \ (AAD_WITH_PAD_LENGTH + WRAP_PAYLOAD_LENGTH + MAC_LENGTH + \ NONCE_LENGTH) +#define IV_SIZE 12 struct qcom_crypto_params { unsigned int authsize; unsigned int authslot_count; unsigned char key_blob[WRAPPED_KEY_SIZE]; - unsigned char iv[12]; + unsigned char iv[IV_SIZE]; unsigned char aad[12]; };