Received: by 2002:ac0:da4c:0:0:0:0:0 with SMTP id a12csp2616349imi; Mon, 25 Jul 2022 03:41:27 -0700 (PDT) X-Google-Smtp-Source: AGRyM1tdVcE0LTtS48XTFMJFyhQtrzl8NTU4eo2AQ71VjPj8Vzcs8c1COn732LjT1TVZDeluTULb X-Received: by 2002:a17:907:1c0c:b0:72e:dd1f:a230 with SMTP id nc12-20020a1709071c0c00b0072edd1fa230mr9694628ejc.8.1658745687219; Mon, 25 Jul 2022 03:41:27 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1658745687; cv=none; d=google.com; s=arc-20160816; b=WGqrP87RQWIvOv3BQG3LC9oEkBG76vMGgEKEPEkCHm3b+J2HcNkDrwKvp6EkU2NBF5 ek/wxmxNn8KOdtUXiHwvd3Yc1uEepTK2l4HbZh/SB+xLlXwyrT3FYrsNQdiZe9CAVcWB rJIqP0uE6FdDqrukP0HMo3c4lcIl1YNNTC+z5v5tAghJzkT0T3lWiGguKMKZroR2cY+i 7fgEwsHsRgV+rZZCT5QAW+86w0iP8/4dG8gDiGt4png9MKzVFMwVviYsoFitvuMtybaH cieePeYQWhcg6yRB+Boa7+LarAuOyo64xf22qkIkv7ribs02YIrz3QBksxjSnEKKsfqv VEpg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=KrJCWlRsp6Yh5occMU3iUikkI7i2NZX+2YAGpskncjU=; b=JQt6mHVFm16Pc29shJcFU9OXl+1zhfsmsl35LL8NyG/+JwvDORrAXfNZndNsO4xPjR j/rwEJRNVxnuxro8oI6eyAX4P+6u8t7F8Vs4ng8Kke4pMgGzIHbnjmUEzNQxilT2VpyX OHKHpDuKWAxfnTAIlAHvTvPMeEmwYiG5yUSTE53Vv6X9pCnY5GzKIMr0L2fDPDkFKsEM xSn/AqJpbkitN2ue9B5qrKsWxu0KXkuwF8T3iw9wrpbNJAh1DJXsCA9wLMQ2PBtBSLk8 ly0oXVW4RQQ+vYY//E2Wi27PSf7VyCps6JLuIvIbPqNs3kjlkxwaAMCHSNYjRqpWkraR vmXg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=drqY6A0e; spf=pass (google.com: domain of linux-crypto-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-crypto-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id g11-20020a056402320b00b0043a7c11a542si12216019eda.147.2022.07.25.03.40.55; Mon, 25 Jul 2022 03:41:27 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-crypto-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=drqY6A0e; spf=pass (google.com: domain of linux-crypto-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-crypto-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230036AbiGYKku (ORCPT + 99 others); Mon, 25 Jul 2022 06:40:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59652 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229694AbiGYKkt (ORCPT ); Mon, 25 Jul 2022 06:40:49 -0400 Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DEC3060F4 for ; Mon, 25 Jul 2022 03:40:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1658745648; x=1690281648; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=bMQTkSo4cdAgEh6YROgs0CilkrJrjDHl3/W1+HdpOZk=; b=drqY6A0eY8kow4jtP6RH9KyO8qOB3jv3EPWiiVqoYm71D7ZTowaUn8wW NskzY72XmLKExeylCwsZOqVijLcTR8Eufz8iD+SFqPZGtQnRgWYmSWP+3 to6vwwIz0sMw/tTdZNbPmXh7ndD1q8mj3RtlplQOcRnaowXGvgt7q7wuS HVMxqo+E07DJ8fIrAJqSoj4WgC06Xi5YWCbV/HKyRQspWdOvLN0jvzHXW 34nk7cnP0QUlaZjX+gQjv77ERBQizFgadiJwhwOP95ORUO8tIv0KNFzLw KcaFKoABxhaDOOik2PRYqgK6p5v4A//20cJ5EFCvCgPb+/KLxreepjtFq g==; X-IronPort-AV: E=McAfee;i="6400,9594,10418"; a="287679554" X-IronPort-AV: E=Sophos;i="5.93,192,1654585200"; d="scan'208";a="287679554" Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 25 Jul 2022 03:40:48 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.93,192,1654585200"; d="scan'208";a="689016282" Received: from 984fee006c34.jf.intel.com ([10.165.126.83]) by FMSMGA003.fm.intel.com with ESMTP; 25 Jul 2022 03:40:48 -0700 From: Srinivas Kerekare To: herbert@gondor.apana.org.au Cc: linux-crypto@vger.kernel.org, qat-linux@intel.com, Srinivas Kerekare , Giovanni Cabiddu , Wojciech Ziemba Subject: [PATCH RESEND] crypto: qat - add check to validate firmware images Date: Mon, 25 Jul 2022 11:40:09 +0100 Message-Id: <20220725104009.76267-1-srinivas.kerekare@intel.com> X-Mailer: git-send-email 2.36.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-7.7 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_NONE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org The function qat_uclo_check_image() validates the MMP and AE firmware images. If the QAT device supports firmware authentication (indicated by the handle to firmware loader), the input signed binary MMP and AE images are validated by parsing the following information: - Header length - Full size of the binary - Type of binary image (MMP or AE Firmware) Firmware binaries use RSA3K for signing and verification. The header length for the RSA3k is 0x384 bytes. All the size field values in the binary are quantified as DWORDS (1 DWORD = 4bytes). On an invalid value the function prints an error message and returns with an error code "EINVAL". Signed-off-by: Srinivas Kerekare Reviewed-by: Giovanni Cabiddu Reviewed-by: Wojciech Ziemba --- drivers/crypto/qat/qat_common/icp_qat_uclo.h | 3 +- drivers/crypto/qat/qat_common/qat_uclo.c | 56 +++++++++++++++++++- 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/drivers/crypto/qat/qat_common/icp_qat_uclo.h b/drivers/crypto/qat/qat_common/icp_qat_uclo.h index 4b36869bf460..69482abdb8b9 100644 --- a/drivers/crypto/qat/qat_common/icp_qat_uclo.h +++ b/drivers/crypto/qat/qat_common/icp_qat_uclo.h @@ -86,7 +86,8 @@ ICP_QAT_CSS_FWSK_MODULUS_LEN(handle) + \ ICP_QAT_CSS_FWSK_EXPONENT_LEN(handle) + \ ICP_QAT_CSS_SIGNATURE_LEN(handle)) -#define ICP_QAT_CSS_MAX_IMAGE_LEN 0x40000 +#define ICP_QAT_CSS_RSA4K_MAX_IMAGE_LEN 0x40000 +#define ICP_QAT_CSS_RSA3K_MAX_IMAGE_LEN 0x30000 #define ICP_QAT_CTX_MODE(ae_mode) ((ae_mode) & 0xf) #define ICP_QAT_NN_MODE(ae_mode) (((ae_mode) >> 0x4) & 0xf) diff --git a/drivers/crypto/qat/qat_common/qat_uclo.c b/drivers/crypto/qat/qat_common/qat_uclo.c index 0fe5a474aa45..b7f7869ef8b2 100644 --- a/drivers/crypto/qat/qat_common/qat_uclo.c +++ b/drivers/crypto/qat/qat_common/qat_uclo.c @@ -1367,6 +1367,48 @@ static void qat_uclo_ummap_auth_fw(struct icp_qat_fw_loader_handle *handle, } } +static int qat_uclo_check_image(struct icp_qat_fw_loader_handle *handle, + char *image, unsigned int size, + unsigned int fw_type) +{ + char *fw_type_name = fw_type ? "MMP" : "AE"; + unsigned int css_dword_size = sizeof(u32); + + if (handle->chip_info->fw_auth) { + struct icp_qat_css_hdr *css_hdr = (struct icp_qat_css_hdr *)image; + unsigned int header_len = ICP_QAT_AE_IMG_OFFSET(handle); + + if ((css_hdr->header_len * css_dword_size) != header_len) + goto err; + if ((css_hdr->size * css_dword_size) != size) + goto err; + if (fw_type != css_hdr->fw_type) + goto err; + if (size <= header_len) + goto err; + size -= header_len; + } + + if (fw_type == CSS_AE_FIRMWARE) { + if (size < sizeof(struct icp_qat_simg_ae_mode *) + + ICP_QAT_SIMG_AE_INIT_SEQ_LEN) + goto err; + if (size > ICP_QAT_CSS_RSA4K_MAX_IMAGE_LEN) + goto err; + } else if (fw_type == CSS_MMP_FIRMWARE) { + if (size > ICP_QAT_CSS_RSA3K_MAX_IMAGE_LEN) + goto err; + } else { + pr_err("QAT: Unsupported firmware type\n"); + return -EINVAL; + } + return 0; + +err: + pr_err("QAT: Invalid %s firmware image\n", fw_type_name); + return -EINVAL; +} + static int qat_uclo_map_auth_fw(struct icp_qat_fw_loader_handle *handle, char *image, unsigned int size, struct icp_qat_fw_auth_desc **desc) @@ -1379,7 +1421,7 @@ static int qat_uclo_map_auth_fw(struct icp_qat_fw_loader_handle *handle, struct icp_qat_simg_ae_mode *simg_ae_mode; struct icp_firml_dram_desc img_desc; - if (size > (ICP_QAT_AE_IMG_OFFSET(handle) + ICP_QAT_CSS_MAX_IMAGE_LEN)) { + if (size > (ICP_QAT_AE_IMG_OFFSET(handle) + ICP_QAT_CSS_RSA4K_MAX_IMAGE_LEN)) { pr_err("QAT: error, input image size overflow %d\n", size); return -EINVAL; } @@ -1547,6 +1589,11 @@ int qat_uclo_wr_mimage(struct icp_qat_fw_loader_handle *handle, { struct icp_qat_fw_auth_desc *desc = NULL; int status = 0; + int ret; + + ret = qat_uclo_check_image(handle, addr_ptr, mem_size, CSS_MMP_FIRMWARE); + if (ret) + return ret; if (handle->chip_info->fw_auth) { status = qat_uclo_map_auth_fw(handle, addr_ptr, mem_size, &desc); @@ -2018,8 +2065,15 @@ static int qat_uclo_wr_suof_img(struct icp_qat_fw_loader_handle *handle) struct icp_qat_fw_auth_desc *desc = NULL; struct icp_qat_suof_handle *sobj_handle = handle->sobj_handle; struct icp_qat_suof_img_hdr *simg_hdr = sobj_handle->img_table.simg_hdr; + int ret; for (i = 0; i < sobj_handle->img_table.num_simgs; i++) { + ret = qat_uclo_check_image(handle, simg_hdr[i].simg_buf, + simg_hdr[i].simg_len, + CSS_AE_FIRMWARE); + if (ret) + return ret; + if (qat_uclo_map_auth_fw(handle, (char *)simg_hdr[i].simg_buf, (unsigned int) -- 2.36.1