xref: /linux-6.15/drivers/crypto/caam/error.c (revision 4f0fa52a)
18e8ec596SKim Phillips /*
28e8ec596SKim Phillips  * CAAM Error Reporting
38e8ec596SKim Phillips  *
48e8ec596SKim Phillips  * Copyright 2009-2011 Freescale Semiconductor, Inc.
58e8ec596SKim Phillips  */
68e8ec596SKim Phillips 
78e8ec596SKim Phillips #include "compat.h"
88e8ec596SKim Phillips #include "regs.h"
98e8ec596SKim Phillips #include "intern.h"
108e8ec596SKim Phillips #include "desc.h"
118e8ec596SKim Phillips #include "jr.h"
128e8ec596SKim Phillips #include "error.h"
138e8ec596SKim Phillips 
1496aef9a8SKim Phillips static const struct {
158e8ec596SKim Phillips 	u8 value;
168e8ec596SKim Phillips 	char *error_text;
178e8ec596SKim Phillips } desc_error_list[] = {
18281922a1SKim Phillips 	{ 0x00, "No error." },
198e8ec596SKim Phillips 	{ 0x01, "SGT Length Error. The descriptor is trying to read "
208e8ec596SKim Phillips 		"more data than is contained in the SGT table." },
21281922a1SKim Phillips 	{ 0x02, "SGT Null Entry Error." },
228e8ec596SKim Phillips 	{ 0x03, "Job Ring Control Error. There is a bad value in the "
238e8ec596SKim Phillips 		"Job Ring Control register." },
248e8ec596SKim Phillips 	{ 0x04, "Invalid Descriptor Command. The Descriptor Command "
258e8ec596SKim Phillips 		"field is invalid." },
268e8ec596SKim Phillips 	{ 0x05, "Reserved." },
278e8ec596SKim Phillips 	{ 0x06, "Invalid KEY Command" },
288e8ec596SKim Phillips 	{ 0x07, "Invalid LOAD Command" },
298e8ec596SKim Phillips 	{ 0x08, "Invalid STORE Command" },
308e8ec596SKim Phillips 	{ 0x09, "Invalid OPERATION Command" },
318e8ec596SKim Phillips 	{ 0x0A, "Invalid FIFO LOAD Command" },
328e8ec596SKim Phillips 	{ 0x0B, "Invalid FIFO STORE Command" },
33281922a1SKim Phillips 	{ 0x0C, "Invalid MOVE/MOVE_LEN Command" },
348e8ec596SKim Phillips 	{ 0x0D, "Invalid JUMP Command. A nonlocal JUMP Command is "
358e8ec596SKim Phillips 		"invalid because the target is not a Job Header "
368e8ec596SKim Phillips 		"Command, or the jump is from a Trusted Descriptor to "
378e8ec596SKim Phillips 		"a Job Descriptor, or because the target Descriptor "
388e8ec596SKim Phillips 		"contains a Shared Descriptor." },
398e8ec596SKim Phillips 	{ 0x0E, "Invalid MATH Command" },
408e8ec596SKim Phillips 	{ 0x0F, "Invalid SIGNATURE Command" },
418e8ec596SKim Phillips 	{ 0x10, "Invalid Sequence Command. A SEQ IN PTR OR SEQ OUT PTR "
428e8ec596SKim Phillips 		"Command is invalid or a SEQ KEY, SEQ LOAD, SEQ FIFO "
438e8ec596SKim Phillips 		"LOAD, or SEQ FIFO STORE decremented the input or "
448e8ec596SKim Phillips 		"output sequence length below 0. This error may result "
458e8ec596SKim Phillips 		"if a built-in PROTOCOL Command has encountered a "
468e8ec596SKim Phillips 		"malformed PDU." },
478e8ec596SKim Phillips 	{ 0x11, "Skip data type invalid. The type must be 0xE or 0xF."},
488e8ec596SKim Phillips 	{ 0x12, "Shared Descriptor Header Error" },
498e8ec596SKim Phillips 	{ 0x13, "Header Error. Invalid length or parity, or certain "
508e8ec596SKim Phillips 		"other problems." },
518e8ec596SKim Phillips 	{ 0x14, "Burster Error. Burster has gotten to an illegal "
528e8ec596SKim Phillips 		"state" },
538e8ec596SKim Phillips 	{ 0x15, "Context Register Length Error. The descriptor is "
548e8ec596SKim Phillips 		"trying to read or write past the end of the Context "
558e8ec596SKim Phillips 		"Register. A SEQ LOAD or SEQ STORE with the VLF bit "
568e8ec596SKim Phillips 		"set was executed with too large a length in the "
578e8ec596SKim Phillips 		"variable length register (VSOL for SEQ STORE or VSIL "
588e8ec596SKim Phillips 		"for SEQ LOAD)." },
598e8ec596SKim Phillips 	{ 0x16, "DMA Error" },
608e8ec596SKim Phillips 	{ 0x17, "Reserved." },
618e8ec596SKim Phillips 	{ 0x1A, "Job failed due to JR reset" },
628e8ec596SKim Phillips 	{ 0x1B, "Job failed due to Fail Mode" },
638e8ec596SKim Phillips 	{ 0x1C, "DECO Watchdog timer timeout error" },
648e8ec596SKim Phillips 	{ 0x1D, "DECO tried to copy a key from another DECO but the "
658e8ec596SKim Phillips 		"other DECO's Key Registers were locked" },
668e8ec596SKim Phillips 	{ 0x1E, "DECO attempted to copy data from a DECO that had an "
678e8ec596SKim Phillips 		"unmasked Descriptor error" },
688e8ec596SKim Phillips 	{ 0x1F, "LIODN error. DECO was trying to share from itself or "
698e8ec596SKim Phillips 		"from another DECO but the two Non-SEQ LIODN values "
708e8ec596SKim Phillips 		"didn't match or the 'shared from' DECO's Descriptor "
718e8ec596SKim Phillips 		"required that the SEQ LIODNs be the same and they "
728e8ec596SKim Phillips 		"aren't." },
738e8ec596SKim Phillips 	{ 0x20, "DECO has completed a reset initiated via the DRR "
748e8ec596SKim Phillips 		"register" },
758e8ec596SKim Phillips 	{ 0x21, "Nonce error. When using EKT (CCM) key encryption "
768e8ec596SKim Phillips 		"option in the FIFO STORE Command, the Nonce counter "
778e8ec596SKim Phillips 		"reached its maximum value and this encryption mode "
788e8ec596SKim Phillips 		"can no longer be used." },
798e8ec596SKim Phillips 	{ 0x22, "Meta data is too large (> 511 bytes) for TLS decap "
808e8ec596SKim Phillips 		"(input frame; block ciphers) and IPsec decap (output "
818e8ec596SKim Phillips 		"frame, when doing the next header byte update) and "
828e8ec596SKim Phillips 		"DCRC (output frame)." },
83281922a1SKim Phillips 	{ 0x23, "Read Input Frame error" },
84281922a1SKim Phillips 	{ 0x24, "JDKEK, TDKEK or TDSK not loaded error" },
858e8ec596SKim Phillips 	{ 0x80, "DNR (do not run) error" },
868e8ec596SKim Phillips 	{ 0x81, "undefined protocol command" },
878e8ec596SKim Phillips 	{ 0x82, "invalid setting in PDB" },
888e8ec596SKim Phillips 	{ 0x83, "Anti-replay LATE error" },
898e8ec596SKim Phillips 	{ 0x84, "Anti-replay REPLAY error" },
908e8ec596SKim Phillips 	{ 0x85, "Sequence number overflow" },
918e8ec596SKim Phillips 	{ 0x86, "Sigver invalid signature" },
928e8ec596SKim Phillips 	{ 0x87, "DSA Sign Illegal test descriptor" },
938e8ec596SKim Phillips 	{ 0x88, "Protocol Format Error - A protocol has seen an error "
948e8ec596SKim Phillips 		"in the format of data received. When running RSA, "
958e8ec596SKim Phillips 		"this means that formatting with random padding was "
968e8ec596SKim Phillips 		"used, and did not follow the form: 0x00, 0x02, 8-to-N "
978e8ec596SKim Phillips 		"bytes of non-zero pad, 0x00, F data." },
988e8ec596SKim Phillips 	{ 0x89, "Protocol Size Error - A protocol has seen an error in "
998e8ec596SKim Phillips 		"size. When running RSA, pdb size N < (size of F) when "
1008e8ec596SKim Phillips 		"no formatting is used; or pdb size N < (F + 11) when "
1018e8ec596SKim Phillips 		"formatting is used." },
1028e8ec596SKim Phillips 	{ 0xC1, "Blob Command error: Undefined mode" },
1038e8ec596SKim Phillips 	{ 0xC2, "Blob Command error: Secure Memory Blob mode error" },
1048e8ec596SKim Phillips 	{ 0xC4, "Blob Command error: Black Blob key or input size "
1058e8ec596SKim Phillips 		"error" },
1068e8ec596SKim Phillips 	{ 0xC5, "Blob Command error: Invalid key destination" },
1078e8ec596SKim Phillips 	{ 0xC8, "Blob Command error: Trusted/Secure mode error" },
1088e8ec596SKim Phillips 	{ 0xF0, "IPsec TTL or hop limit field either came in as 0, "
1098e8ec596SKim Phillips 		"or was decremented to 0" },
1108e8ec596SKim Phillips 	{ 0xF1, "3GPP HFN matches or exceeds the Threshold" },
1118e8ec596SKim Phillips };
1129724d7adSMarek Vasut 
1139724d7adSMarek Vasut static const char * const cha_id_list[] = {
1149724d7adSMarek Vasut 	"",
1159724d7adSMarek Vasut 	"AES",
1169724d7adSMarek Vasut 	"DES",
1179724d7adSMarek Vasut 	"ARC4",
1189724d7adSMarek Vasut 	"MDHA",
1199724d7adSMarek Vasut 	"RNG",
1209724d7adSMarek Vasut 	"SNOW f8",
1219724d7adSMarek Vasut 	"Kasumi f8/9",
1229724d7adSMarek Vasut 	"PKHA",
1239724d7adSMarek Vasut 	"CRCA",
1249724d7adSMarek Vasut 	"SNOW f9",
1259724d7adSMarek Vasut 	"ZUCE",
1269724d7adSMarek Vasut 	"ZUCA",
1279724d7adSMarek Vasut };
1289724d7adSMarek Vasut 
1299724d7adSMarek Vasut static const char * const err_id_list[] = {
1309724d7adSMarek Vasut 	"No error.",
1319724d7adSMarek Vasut 	"Mode error.",
1329724d7adSMarek Vasut 	"Data size error.",
1339724d7adSMarek Vasut 	"Key size error.",
1349724d7adSMarek Vasut 	"PKHA A memory size error.",
1359724d7adSMarek Vasut 	"PKHA B memory size error.",
1369724d7adSMarek Vasut 	"Data arrived out of sequence error.",
1379724d7adSMarek Vasut 	"PKHA divide-by-zero error.",
1389724d7adSMarek Vasut 	"PKHA modulus even error.",
1399724d7adSMarek Vasut 	"DES key parity error.",
1409724d7adSMarek Vasut 	"ICV check failed.",
1419724d7adSMarek Vasut 	"Hardware error.",
1429724d7adSMarek Vasut 	"Unsupported CCM AAD size.",
1439724d7adSMarek Vasut 	"Class 1 CHA is not reset",
1449724d7adSMarek Vasut 	"Invalid CHA combination was selected",
1459724d7adSMarek Vasut 	"Invalid CHA selected.",
1469724d7adSMarek Vasut };
1479724d7adSMarek Vasut 
1489724d7adSMarek Vasut static const char * const rng_err_id_list[] = {
1499724d7adSMarek Vasut 	"",
1509724d7adSMarek Vasut 	"",
1519724d7adSMarek Vasut 	"",
1529724d7adSMarek Vasut 	"Instantiate",
1539724d7adSMarek Vasut 	"Not instantiated",
1549724d7adSMarek Vasut 	"Test instantiate",
1559724d7adSMarek Vasut 	"Prediction resistance",
1569724d7adSMarek Vasut 	"Prediction resistance and test request",
1579724d7adSMarek Vasut 	"Uninstantiate",
1589724d7adSMarek Vasut 	"Secure key generation",
1599724d7adSMarek Vasut };
1609724d7adSMarek Vasut 
1619724d7adSMarek Vasut #define SPRINTFCAT(str, format, param, max_alloc)		\
1629724d7adSMarek Vasut {								\
1639724d7adSMarek Vasut 	char *tmp;						\
1649724d7adSMarek Vasut 								\
1659724d7adSMarek Vasut 	tmp = kmalloc(sizeof(format) + max_alloc, GFP_ATOMIC);	\
1669724d7adSMarek Vasut 	sprintf(tmp, format, param);				\
1679724d7adSMarek Vasut 	strcat(str, tmp);					\
1689724d7adSMarek Vasut 	kfree(tmp);						\
1699724d7adSMarek Vasut }
1709724d7adSMarek Vasut 
1718a475826SMarek Vasut static void report_ccb_status(struct device *jrdev, u32 status,
172e75880ddSMarek Vasut 			      const char *error, char *__outstr)
1739724d7adSMarek Vasut {
1749724d7adSMarek Vasut 	u8 cha_id = (status & JRSTA_CCBERR_CHAID_MASK) >>
1759724d7adSMarek Vasut 		    JRSTA_CCBERR_CHAID_SHIFT;
1769724d7adSMarek Vasut 	u8 err_id = status & JRSTA_CCBERR_ERRID_MASK;
177526243ccSMarek Vasut 	u8 idx = (status & JRSTA_DECOERR_INDEX_MASK) >>
178526243ccSMarek Vasut 		  JRSTA_DECOERR_INDEX_SHIFT;
1791e16322dSMarek Vasut 	char *idx_str;
1801e16322dSMarek Vasut 	const char *cha_str = "unidentified cha_id value 0x";
1811e16322dSMarek Vasut 	char cha_err_code[3] = { 0 };
1821e16322dSMarek Vasut 	const char *err_str = "unidentified err_id value 0x";
1831e16322dSMarek Vasut 	char err_err_code[3] = { 0 };
1848a475826SMarek Vasut 
185526243ccSMarek Vasut 	if (status & JRSTA_DECOERR_JUMP)
1861e16322dSMarek Vasut 		idx_str = "jump tgt desc idx";
187526243ccSMarek Vasut 	else
1881e16322dSMarek Vasut 		idx_str = "desc idx";
189526243ccSMarek Vasut 
1901e16322dSMarek Vasut 	if (cha_id < ARRAY_SIZE(cha_id_list))
1911e16322dSMarek Vasut 		cha_str = cha_id_list[cha_id];
1921e16322dSMarek Vasut 	else
1931e16322dSMarek Vasut 		snprintf(cha_err_code, sizeof(cha_err_code), "%02x", cha_id);
1949724d7adSMarek Vasut 
1959724d7adSMarek Vasut 	if ((cha_id << JRSTA_CCBERR_CHAID_SHIFT) == JRSTA_CCBERR_CHAID_RNG &&
1969724d7adSMarek Vasut 	    err_id < ARRAY_SIZE(rng_err_id_list) &&
1979724d7adSMarek Vasut 	    strlen(rng_err_id_list[err_id])) {
1989724d7adSMarek Vasut 		/* RNG-only error */
1991e16322dSMarek Vasut 		err_str = rng_err_id_list[err_id];
2001e16322dSMarek Vasut 	} else if (err_id < ARRAY_SIZE(err_id_list))
2011e16322dSMarek Vasut 		err_str = err_id_list[err_id];
2021e16322dSMarek Vasut 	else
2031e16322dSMarek Vasut 		snprintf(err_err_code, sizeof(err_err_code), "%02x", err_id);
204e75880ddSMarek Vasut 
2051e16322dSMarek Vasut 	dev_err(jrdev, "%08x: %s: %s %d: %s%s: %s%s\n",
2061e16322dSMarek Vasut 		status, error, idx_str, idx,
2071e16322dSMarek Vasut 		cha_str, cha_err_code,
2081e16322dSMarek Vasut 		err_str, err_err_code);
2099724d7adSMarek Vasut }
2109724d7adSMarek Vasut 
2118a475826SMarek Vasut static void report_jump_status(struct device *jrdev, u32 status,
2128a475826SMarek Vasut 			       const char *error, char *outstr)
2139724d7adSMarek Vasut {
214e75880ddSMarek Vasut 	dev_err(jrdev, "%08x: %s: %s() not implemented\n",
215e75880ddSMarek Vasut 		status, error, __func__);
2169724d7adSMarek Vasut }
2179724d7adSMarek Vasut 
2188a475826SMarek Vasut static void report_deco_status(struct device *jrdev, u32 status,
219e75880ddSMarek Vasut 			       const char *error, char *__outstr)
2209724d7adSMarek Vasut {
221*4f0fa52aSMarek Vasut 	u8 err_id = status & JRSTA_DECOERR_ERROR_MASK;
222526243ccSMarek Vasut 	u8 idx = (status & JRSTA_DECOERR_INDEX_MASK) >>
223526243ccSMarek Vasut 		  JRSTA_DECOERR_INDEX_SHIFT;
224*4f0fa52aSMarek Vasut 	char *idx_str;
225*4f0fa52aSMarek Vasut 	char *err_str = "unidentified error value 0x";
226*4f0fa52aSMarek Vasut 	char err_err_code[3] = { 0 };
2278e8ec596SKim Phillips 	int i;
2288e8ec596SKim Phillips 
229526243ccSMarek Vasut 	if (status & JRSTA_DECOERR_JUMP)
230*4f0fa52aSMarek Vasut 		idx_str = "jump tgt desc idx";
231526243ccSMarek Vasut 	else
232*4f0fa52aSMarek Vasut 		idx_str = "desc idx";
2338e8ec596SKim Phillips 
2346d00376aSDan Carpenter 	for (i = 0; i < ARRAY_SIZE(desc_error_list); i++)
235*4f0fa52aSMarek Vasut 		if (desc_error_list[i].value == err_id)
2368e8ec596SKim Phillips 			break;
2378e8ec596SKim Phillips 
238*4f0fa52aSMarek Vasut 	if (i != ARRAY_SIZE(desc_error_list) && desc_error_list[i].error_text)
239*4f0fa52aSMarek Vasut 		err_str = desc_error_list[i].error_text;
240*4f0fa52aSMarek Vasut 	else
241*4f0fa52aSMarek Vasut 		snprintf(err_err_code, sizeof(err_err_code), "%02x", err_id);
242e75880ddSMarek Vasut 
243*4f0fa52aSMarek Vasut 	dev_err(jrdev, "%08x: %s: %s %d: %s%s\n",
244*4f0fa52aSMarek Vasut 		status, error, idx_str, idx, err_str, err_err_code);
2458e8ec596SKim Phillips }
2468e8ec596SKim Phillips 
2478a475826SMarek Vasut static void report_jr_status(struct device *jrdev, u32 status,
2488a475826SMarek Vasut 			     const char *error, char *outstr)
2498e8ec596SKim Phillips {
250e75880ddSMarek Vasut 	dev_err(jrdev, "%08x: %s: %s() not implemented\n",
251e75880ddSMarek Vasut 		status, error, __func__);
2528e8ec596SKim Phillips }
2538e8ec596SKim Phillips 
2548a475826SMarek Vasut static void report_cond_code_status(struct device *jrdev, u32 status,
2558a475826SMarek Vasut 				    const char *error, char *outstr)
2568e8ec596SKim Phillips {
257e75880ddSMarek Vasut 	dev_err(jrdev, "%08x: %s: %s() not implemented\n",
258e75880ddSMarek Vasut 		status, error, __func__);
2598e8ec596SKim Phillips }
2608e8ec596SKim Phillips 
261fa9659cdSMarek Vasut void caam_jr_strstatus(struct device *jrdev, u32 status)
2628e8ec596SKim Phillips {
26396aef9a8SKim Phillips 	static const struct stat_src {
2648a475826SMarek Vasut 		void (*report_ssed)(struct device *jrdev, u32 status,
2658a475826SMarek Vasut 				    const char *error, char *outstr);
2668a475826SMarek Vasut 		const char *error;
2678e8ec596SKim Phillips 	} status_src[] = {
2688e8ec596SKim Phillips 		{ NULL, "No error" },
2698e8ec596SKim Phillips 		{ NULL, NULL },
2708e8ec596SKim Phillips 		{ report_ccb_status, "CCB" },
2718e8ec596SKim Phillips 		{ report_jump_status, "Jump" },
2728e8ec596SKim Phillips 		{ report_deco_status, "DECO" },
2738e8ec596SKim Phillips 		{ NULL, NULL },
2748e8ec596SKim Phillips 		{ report_jr_status, "Job Ring" },
2758e8ec596SKim Phillips 		{ report_cond_code_status, "Condition Code" },
2768e8ec596SKim Phillips 	};
2778e8ec596SKim Phillips 	u32 ssrc = status >> JRSTA_SSRC_SHIFT;
2788e8ec596SKim Phillips 
279867e1ee3SMarek Vasut 	/*
280867e1ee3SMarek Vasut 	 * If there is no further error handling function, just
281867e1ee3SMarek Vasut 	 * print the error code, error string and exit.
282867e1ee3SMarek Vasut 	 */
283867e1ee3SMarek Vasut 	if (!status_src[ssrc].report_ssed) {
284867e1ee3SMarek Vasut 		dev_err(jrdev, "%08x: %s: \n", status, status_src[ssrc].error);
285867e1ee3SMarek Vasut 		return;
286867e1ee3SMarek Vasut 	}
287867e1ee3SMarek Vasut 
2888a475826SMarek Vasut 	status_src[ssrc].report_ssed(jrdev, status,
289e75880ddSMarek Vasut 			status_src[ssrc].error, NULL);
2908e8ec596SKim Phillips }
2918e8ec596SKim Phillips EXPORT_SYMBOL(caam_jr_strstatus);
292