1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright 2018-2020 NXP
4  *
5  * Brief   Cryptographic library using the NXP CAAM driver.
6  *         Mathematical Modulus operation implementation.
7  */
8 #include <drvcrypt.h>
9 #include <drvcrypt_math.h>
10 #include <string.h>
11 #include <utee_defines.h>
12 #include <util.h>
13 
drvcrypt_xor_mod_n(struct drvcrypt_mod_op * data)14 TEE_Result drvcrypt_xor_mod_n(struct drvcrypt_mod_op *data)
15 {
16 	TEE_Result ret = TEE_ERROR_GENERIC;
17 	struct drvcrypt_math *math = NULL;
18 
19 	if (!data->a.data || !data->a.length || !data->b.data ||
20 	    !data->b.length || !data->result.data || !data->result.length ||
21 	    !data->n.length)
22 		return TEE_ERROR_BAD_PARAMETERS;
23 
24 	if (data->result.length < data->n.length)
25 		return TEE_ERROR_BAD_PARAMETERS;
26 
27 	math = drvcrypt_get_ops(CRYPTO_MATH);
28 	if (math) {
29 		/* Operation done by Math driver */
30 		ret = math->xor_mod_n(data);
31 	} else {
32 		/* Operation done by Software */
33 		size_t min = 0, idx = 0;
34 
35 		/* Calculate the minimum size to do A xor B */
36 		min = MIN(data->a.length, data->b.length);
37 		min = MIN(min, data->n.length);
38 
39 		for (; idx < min; idx++)
40 			data->result.data[idx] =
41 				data->a.data[idx] ^ data->b.data[idx];
42 
43 		if (min < data->n.length) {
44 			/* Complete result to make a N modulus number */
45 			if (data->a.length > min) {
46 				memcpy(&data->result.data[idx],
47 				       &data->a.data[idx],
48 				       data->n.length - min);
49 			} else if (data->b.length > min) {
50 				memcpy(&data->result.data[idx],
51 				       &data->b.data[idx],
52 				       data->n.length - min);
53 			} else {
54 				memset(&data->result.data[idx], 0,
55 				       data->n.length - min);
56 			}
57 		}
58 
59 		ret = TEE_SUCCESS;
60 	}
61 
62 	return ret;
63 }
64