1 /*************************************************************************/ /*!
3 @Title Services firmware load and access routines for Linux
4 @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
5 @Description Device specific functions
6 @License Dual MIT/GPLv2
8 The contents of this file are subject to the MIT license as set out below.
10 Permission is hereby granted, free of charge, to any person obtaining a copy
11 of this software and associated documentation files (the "Software"), to deal
12 in the Software without restriction, including without limitation the rights
13 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 copies of the Software, and to permit persons to whom the Software is
15 furnished to do so, subject to the following conditions:
17 The above copyright notice and this permission notice shall be included in
18 all copies or substantial portions of the Software.
20 Alternatively, the contents of this file may be used under the terms of
21 the GNU General Public License Version 2 ("GPL") in which case the provisions
22 of GPL are applicable instead of those above.
24 If you wish to allow use of your version of this file only under the terms of
25 GPL, and not to allow others to use your version of this file under the terms
26 of the MIT license, indicate your decision by deleting the provisions above
27 and replace them with the notice and other provisions required by GPL as set
28 out in the file called "GPL-COPYING" included in this distribution. If you do
29 not delete the provisions above, a recipient may use your version of this file
30 under the terms of either the MIT license or GPL.
32 This License is also included in this distribution in the file called
35 EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
36 PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
37 BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
38 PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
39 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
40 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
41 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
42 */ /**************************************************************************/
44 #include <linux/firmware.h>
45 #include <linux/version.h>
46 #include <linux/kernel.h>
47 #include <linux/err.h>
50 #include "module_common.h"
51 #include "rgxfwload.h"
52 #include "pvr_debug.h"
57 const struct firmware sFW;
60 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0)) && defined(RGX_FW_SIGNED)
62 /* The Linux kernel does not support the RSA PSS padding mode. It only
63 * supports the legacy PKCS#1 padding mode.
65 #if defined(RGX_FW_PKCS1_PSS_PADDING)
66 #error Linux does not support verification of RSA PSS padded signatures
69 #include <crypto/public_key.h>
70 #include <crypto/hash_info.h>
71 #include <crypto/hash.h>
73 #include <keys/asymmetric-type.h>
74 #include <keys/system_keyring.h>
78 static bool VerifyFirmware(const struct firmware *psFW)
80 struct FirmwareSignatureHeader *psHeader;
81 struct public_key_signature *psPKS;
82 unsigned char *szKeyID, *pcKeyID;
83 size_t uDigestSize, uDescSize;
84 void *pvSignature, *pvSigner;
85 struct crypto_shash *psTFM;
86 struct shash_desc *psDesc;
87 uint32_t ui32SignatureLen;
88 bool bVerified = false;
93 if (psFW->size < FW_SIGN_BACKWARDS_OFFSET)
95 PVR_DPF((PVR_DBG_ERROR, "%s: Firmware is too small (%zu bytes)",
96 __func__, psFW->size));
97 goto err_release_firmware;
100 psHeader = (struct FirmwareSignatureHeader *)
101 (psFW->data + (psFW->size - FW_SIGN_BACKWARDS_OFFSET));
103 /* All derived from u8 so can't be exploited to flow out of this page */
104 pvSigner = (u8 *)psHeader + sizeof(struct FirmwareSignatureHeader);
105 pcKeyID = (unsigned char *)((u8 *)pvSigner + psHeader->ui8SignerLen);
106 pvSignature = (u8 *)pcKeyID + psHeader->ui8KeyIDLen;
108 /* We cannot update KERNEL_RO in-place, so we must copy the len */
109 ui32SignatureLen = ntohl(psHeader->ui32SignatureLen);
111 if (psHeader->ui8Algo >= PKEY_ALGO__LAST)
113 PVR_DPF((PVR_DBG_ERROR, "%s: Public key algorithm %u is not supported",
114 __func__, psHeader->ui8Algo));
115 goto err_release_firmware;
118 if (psHeader->ui8HashAlgo >= PKEY_HASH__LAST)
120 PVR_DPF((PVR_DBG_ERROR, "%s: Hash algorithm %u is not supported",
121 __func__, psHeader->ui8HashAlgo));
122 goto err_release_firmware;
125 if (psHeader->ui8IDType != PKEY_ID_X509)
127 PVR_DPF((PVR_DBG_ERROR, "%s: Only asymmetric X.509 PKI certificates "
128 "are supported", __func__));
129 goto err_release_firmware;
132 /* Generate a hash of the fw data (including the padding) */
134 psTFM = crypto_alloc_shash(hash_algo_name[psHeader->ui8HashAlgo], 0, 0);
137 PVR_DPF((PVR_DBG_ERROR, "%s: crypto_alloc_shash() failed (%ld)",
138 __func__, PTR_ERR(psTFM)));
139 goto err_release_firmware;
142 uDescSize = crypto_shash_descsize(psTFM) + sizeof(*psDesc);
143 uDigestSize = crypto_shash_digestsize(psTFM);
145 psPKS = kzalloc(sizeof(*psPKS) + uDescSize + uDigestSize, GFP_KERNEL);
147 goto err_free_crypto_shash;
149 psDesc = (struct shash_desc *)((u8 *)psPKS + sizeof(*psPKS));
151 psDesc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
153 psPKS->pkey_algo = psHeader->ui8Algo;
154 psPKS->pkey_hash_algo = psHeader->ui8HashAlgo;
156 psPKS->digest = (u8 *)psPKS + sizeof(*psPKS) + uDescSize;
157 psPKS->digest_size = uDigestSize;
159 res = crypto_shash_init(psDesc);
162 PVR_DPF((PVR_DBG_ERROR, "%s: crypto_shash_init() failed (%d)",
167 res = crypto_shash_finup(psDesc, psFW->data, psFW->size - FW_SIGN_BACKWARDS_OFFSET,
171 PVR_DPF((PVR_DBG_ERROR, "%s: crypto_shash_finup() failed (%d)",
176 /* Populate the MPI with the signature payload */
179 psPKS->rsa.s = mpi_read_raw_data(pvSignature, ui32SignatureLen);
182 PVR_DPF((PVR_DBG_ERROR, "%s: mpi_read_raw_data() failed", __func__));
186 /* Look up the key we'll use to verify this signature */
188 szKeyID = kmalloc(psHeader->ui8SignerLen + 2 +
189 psHeader->ui8KeyIDLen * 2 + 1, GFP_KERNEL);
193 memcpy(szKeyID, pvSigner, psHeader->ui8SignerLen);
195 szKeyID[psHeader->ui8SignerLen + 0] = ':';
196 szKeyID[psHeader->ui8SignerLen + 1] = ' ';
198 for (i = 0; i < psHeader->ui8KeyIDLen; i++)
199 sprintf(&szKeyID[psHeader->ui8SignerLen + 2 + i * 2],
202 szKeyID[psHeader->ui8SignerLen + 2 + psHeader->ui8KeyIDLen * 2] = 0;
204 hKey = keyring_search(make_key_ref(system_trusted_keyring, 1),
205 &key_type_asymmetric, szKeyID);
208 PVR_DPF((PVR_DBG_ERROR, "Request for unknown key '%s' (%ld)",
209 szKeyID, PTR_ERR(hKey)));
210 goto err_free_keyid_string;
213 res = verify_signature(key_ref_to_ptr(hKey), psPKS);
216 PVR_DPF((PVR_DBG_ERROR, "%s: Firmware digital signature verification "
217 "failed (%d)", __func__, res));
221 PVR_LOG(("Digital signature for '%s' verified successfully.",
225 key_put(key_ref_to_ptr(hKey));
226 err_free_keyid_string:
229 mpi_free(psPKS->rsa.s);
232 err_free_crypto_shash:
233 crypto_free_shash(psTFM);
234 err_release_firmware:
238 #else /* defined(RGX_FW_SIGNED) */
240 static inline bool VerifyFirmware(const struct firmware *psFW)
245 #endif /* defined(RGX_FW_SIGNED) */
247 IMG_INTERNAL struct RGXFW *
248 RGXLoadFirmware(SHARED_DEV_CONNECTION psDeviceNode, const IMG_CHAR *pszBVNCString, const IMG_CHAR *pszBVpNCString)
250 const struct firmware *psFW;
253 if(pszBVNCString != NULL)
255 res = request_firmware(&psFW, pszBVNCString, psDeviceNode->psDevConfig->pvOSDevice);
258 if(pszBVpNCString != NULL)
260 PVR_DPF((PVR_DBG_WARNING, "%s: request_firmware('%s') failed (%d), trying '%s'",
261 __func__, pszBVNCString, res, pszBVpNCString));
262 res = request_firmware(&psFW, pszBVpNCString, psDeviceNode->psDevConfig->pvOSDevice);
266 PVR_DPF((PVR_DBG_WARNING, "%s: request_firmware('%s') failed (%d), trying '%s'",
267 __func__, pszBVpNCString, res, RGX_FW_FILENAME));
268 res = request_firmware(&psFW, RGX_FW_FILENAME, psDeviceNode->psDevConfig->pvOSDevice);
274 res = request_firmware(&psFW, RGX_FW_FILENAME, psDeviceNode->psDevConfig->pvOSDevice);
278 PVR_DPF((PVR_DBG_ERROR, "%s: request_firmware('%s') failed (%d)",
279 __func__, RGX_FW_FILENAME, res));
283 if (!VerifyFirmware(psFW))
285 release_firmware(psFW);
289 return (struct RGXFW *)psFW;
293 RGXUnloadFirmware(struct RGXFW *psRGXFW)
295 const struct firmware *psFW = &psRGXFW->sFW;
297 release_firmware(psFW);
301 RGXFirmwareSize(struct RGXFW *psRGXFW)
303 #if defined(PVRSRV_GPUVIRT_GUESTDRV)
304 PVR_UNREFERENCED_PARAMETER(psRGXFW);
307 const struct firmware *psFW = &psRGXFW->sFW;
313 IMG_INTERNAL const void *
314 RGXFirmwareData(struct RGXFW *psRGXFW)
316 const struct firmware *psFW = &psRGXFW->sFW;
321 /******************************************************************************
322 End of file (rgxfwload.c)
323 ******************************************************************************/