1 /***************************************************************************
2  * Copyright (c) 2024 Microsoft Corporation
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the MIT License which is available at
6  * https://opensource.org/licenses/MIT.
7  *
8  * SPDX-License-Identifier: MIT
9  **************************************************************************/
10 
11 
12 /**************************************************************************/
13 /**************************************************************************/
14 /**                                                                       */
15 /** NetX Crypto Component                                                 */
16 /**                                                                       */
17 /**   AES Encryption                                                      */
18 /**                                                                       */
19 /**************************************************************************/
20 /**************************************************************************/
21 
22 
23 /* Include necessary system files.  */
24 
25 #include "nx_crypto_aes.h"
26 #include "nx_crypto_xcbc_mac.h"
27 
28 #if !defined(NX_CRYPTO_LITTLE_ENDIAN)
29 /*
30     Encryption table for BIG ENDIAN architecture.
31 
32     Lookup table for computing the MixColumns() Transformation with SubBytes applied to input value S.
33     Each entry of this table represents the result of {02} dot S[x,c] | {01} dot S[x,c] | {01} dot S[x,c] | {03} dot S[x,c]. See Equation
34     5.6 on page 18 AES specification(Pub 197)
35 
36     The most significant byte is the result of {02} dot S, and the least significant byte is the result
37     of {03} dot S[x,c].
38  */
39 NX_CRYPTO_AES_TABLE ULONG aes_encryption_table[256] =
40 {
41     0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d, 0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554,
42     0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d, 0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a,
43     0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87, 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b,
44     0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea, 0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b,
45     0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a, 0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f,
46     0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108, 0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f,
47     0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e, 0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5,
48     0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d, 0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f,
49     0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e, 0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb,
50     0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce, 0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497,
51     0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c, 0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed,
52     0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b, 0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a,
53     0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16, 0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594,
54     0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81, 0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3,
55     0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a, 0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504,
56     0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163, 0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d,
57     0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f, 0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739,
58     0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47, 0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395,
59     0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f, 0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883,
60     0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c, 0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76,
61     0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e, 0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4,
62     0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6, 0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b,
63     0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7, 0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0,
64     0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25, 0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818,
65     0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72, 0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651,
66     0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21, 0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85,
67     0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa, 0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12,
68     0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0, 0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9,
69     0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133, 0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7,
70     0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920, 0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a,
71     0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17, 0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8,
72     0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11, 0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a
73 };
74 
75 
76 /*
77    Decryption table for LITTLE ENDIAN architecture.
78 
79    Lookup table for computing the InvMixColumns() Transformation with InvSubBytes applied to input
80    value S.  Each entry of this table represents
81    the result of {0e} dot S[x,c] | {09} dot S[x,c] | {0d} dot S[x,c] | {0b} dot S[x,c]. See Equation
82    5.10 on page 23 AES specification(Pub 197)
83 
84    The most significant byte is the result of {0e} dot S, and the least significant byte is the result
85    of {0b} dot S[x,c].
86  */
87 NX_CRYPTO_AES_TABLE ULONG aes_decryption_table[256] =
88 {
89     0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96, 0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393,
90     0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25, 0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f,
91     0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1, 0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6,
92     0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da, 0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844,
93     0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd, 0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4,
94     0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45, 0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94,
95     0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7, 0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a,
96     0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5, 0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c,
97     0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1, 0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a,
98     0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75, 0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051,
99     0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46, 0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff,
100     0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77, 0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb,
101     0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000, 0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e,
102     0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927, 0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a,
103     0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e, 0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16,
104     0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d, 0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8,
105     0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd, 0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34,
106     0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163, 0xd731dcca, 0x42638510, 0x13972240, 0x84c61120,
107     0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d, 0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0,
108     0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422, 0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef,
109     0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36, 0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4,
110     0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662, 0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5,
111     0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3, 0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b,
112     0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8, 0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6,
113     0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6, 0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0,
114     0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815, 0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f,
115     0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df, 0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f,
116     0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e, 0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713,
117     0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89, 0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c,
118     0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf, 0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86,
119     0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f, 0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541,
120     0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190, 0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742
121 };
122 
123 /*
124     Inverse Mix Table for LITTLE ENDIAN architecture.
125     Lookup table for computing the InvMixColumns() Transformation.  Each entry of this table represents
126     the result of {0e} dot S[x,c] | {09} dot S[x,c] | {0d} dot S[x,c] | {0b} dot S[x,c]. See Equation
127     5.10 on page 23 AES specification(Pub 197)
128 
129     The most significant byte is the result of {0e} dot S, and the least significant byte is the result
130     of {0b} dot S[x,c].
131  */
132 NX_CRYPTO_AES_TABLE ULONG aes_inv_mix_table[256] =
133 {
134     0x00000000, 0x0e090d0b, 0x1c121a16, 0x121b171d, 0x3824342c, 0x362d3927, 0x24362e3a, 0x2a3f2331,
135     0x70486858, 0x7e416553, 0x6c5a724e, 0x62537f45, 0x486c5c74, 0x4665517f, 0x547e4662, 0x5a774b69,
136     0xe090d0b0, 0xee99ddbb, 0xfc82caa6, 0xf28bc7ad, 0xd8b4e49c, 0xd6bde997, 0xc4a6fe8a, 0xcaaff381,
137     0x90d8b8e8, 0x9ed1b5e3, 0x8ccaa2fe, 0x82c3aff5, 0xa8fc8cc4, 0xa6f581cf, 0xb4ee96d2, 0xbae79bd9,
138     0xdb3bbb7b, 0xd532b670, 0xc729a16d, 0xc920ac66, 0xe31f8f57, 0xed16825c, 0xff0d9541, 0xf104984a,
139     0xab73d323, 0xa57ade28, 0xb761c935, 0xb968c43e, 0x9357e70f, 0x9d5eea04, 0x8f45fd19, 0x814cf012,
140     0x3bab6bcb, 0x35a266c0, 0x27b971dd, 0x29b07cd6, 0x038f5fe7, 0x0d8652ec, 0x1f9d45f1, 0x119448fa,
141     0x4be30393, 0x45ea0e98, 0x57f11985, 0x59f8148e, 0x73c737bf, 0x7dce3ab4, 0x6fd52da9, 0x61dc20a2,
142     0xad766df6, 0xa37f60fd, 0xb16477e0, 0xbf6d7aeb, 0x955259da, 0x9b5b54d1, 0x894043cc, 0x87494ec7,
143     0xdd3e05ae, 0xd33708a5, 0xc12c1fb8, 0xcf2512b3, 0xe51a3182, 0xeb133c89, 0xf9082b94, 0xf701269f,
144     0x4de6bd46, 0x43efb04d, 0x51f4a750, 0x5ffdaa5b, 0x75c2896a, 0x7bcb8461, 0x69d0937c, 0x67d99e77,
145     0x3daed51e, 0x33a7d815, 0x21bccf08, 0x2fb5c203, 0x058ae132, 0x0b83ec39, 0x1998fb24, 0x1791f62f,
146     0x764dd68d, 0x7844db86, 0x6a5fcc9b, 0x6456c190, 0x4e69e2a1, 0x4060efaa, 0x527bf8b7, 0x5c72f5bc,
147     0x0605bed5, 0x080cb3de, 0x1a17a4c3, 0x141ea9c8, 0x3e218af9, 0x302887f2, 0x223390ef, 0x2c3a9de4,
148     0x96dd063d, 0x98d40b36, 0x8acf1c2b, 0x84c61120, 0xaef93211, 0xa0f03f1a, 0xb2eb2807, 0xbce2250c,
149     0xe6956e65, 0xe89c636e, 0xfa877473, 0xf48e7978, 0xdeb15a49, 0xd0b85742, 0xc2a3405f, 0xccaa4d54,
150     0x41ecdaf7, 0x4fe5d7fc, 0x5dfec0e1, 0x53f7cdea, 0x79c8eedb, 0x77c1e3d0, 0x65daf4cd, 0x6bd3f9c6,
151     0x31a4b2af, 0x3fadbfa4, 0x2db6a8b9, 0x23bfa5b2, 0x09808683, 0x07898b88, 0x15929c95, 0x1b9b919e,
152     0xa17c0a47, 0xaf75074c, 0xbd6e1051, 0xb3671d5a, 0x99583e6b, 0x97513360, 0x854a247d, 0x8b432976,
153     0xd134621f, 0xdf3d6f14, 0xcd267809, 0xc32f7502, 0xe9105633, 0xe7195b38, 0xf5024c25, 0xfb0b412e,
154     0x9ad7618c, 0x94de6c87, 0x86c57b9a, 0x88cc7691, 0xa2f355a0, 0xacfa58ab, 0xbee14fb6, 0xb0e842bd,
155     0xea9f09d4, 0xe49604df, 0xf68d13c2, 0xf8841ec9, 0xd2bb3df8, 0xdcb230f3, 0xcea927ee, 0xc0a02ae5,
156     0x7a47b13c, 0x744ebc37, 0x6655ab2a, 0x685ca621, 0x42638510, 0x4c6a881b, 0x5e719f06, 0x5078920d,
157     0x0a0fd964, 0x0406d46f, 0x161dc372, 0x1814ce79, 0x322bed48, 0x3c22e043, 0x2e39f75e, 0x2030fa55,
158     0xec9ab701, 0xe293ba0a, 0xf088ad17, 0xfe81a01c, 0xd4be832d, 0xdab78e26, 0xc8ac993b, 0xc6a59430,
159     0x9cd2df59, 0x92dbd252, 0x80c0c54f, 0x8ec9c844, 0xa4f6eb75, 0xaaffe67e, 0xb8e4f163, 0xb6edfc68,
160     0x0c0a67b1, 0x02036aba, 0x10187da7, 0x1e1170ac, 0x342e539d, 0x3a275e96, 0x283c498b, 0x26354480,
161     0x7c420fe9, 0x724b02e2, 0x605015ff, 0x6e5918f4, 0x44663bc5, 0x4a6f36ce, 0x587421d3, 0x567d2cd8,
162     0x37a10c7a, 0x39a80171, 0x2bb3166c, 0x25ba1b67, 0x0f853856, 0x018c355d, 0x13972240, 0x1d9e2f4b,
163     0x47e96422, 0x49e06929, 0x5bfb7e34, 0x55f2733f, 0x7fcd500e, 0x71c45d05, 0x63df4a18, 0x6dd64713,
164     0xd731dcca, 0xd938d1c1, 0xcb23c6dc, 0xc52acbd7, 0xef15e8e6, 0xe11ce5ed, 0xf307f2f0, 0xfd0efffb,
165     0xa779b492, 0xa970b999, 0xbb6bae84, 0xb562a38f, 0x9f5d80be, 0x91548db5, 0x834f9aa8, 0x8d4697a3
166 };
167 
168 #else
169 
170 /*
171     Encryption table for LITTLE ENDIAN architecture.
172 
173     Lookup table for computing the MixColumns() Transformation with SubBytes applied to input value S.
174     Each entry of this table represents the result of {02} dot S[x,c] | {01} dot S[x,c] | {01} dot S[x,c] | {03} dot S[x,c]. See Equation
175     5.6 on page 18 AES specification(Pub 197)
176 
177     The most significant byte is the result of {02} dot S, and the least significant byte is the result
178     of {03} dot S[x,c].
179  */
180 
181 NX_CRYPTO_AES_TABLE ULONG aes_encryption_table[256] =
182 {
183     0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, 0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591,
184     0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56, 0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec,
185     0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa, 0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb,
186     0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, 0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b,
187     0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c, 0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83,
188     0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9, 0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a,
189     0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d, 0x28181830, 0xa1969637, 0x0f05050a, 0xb59a9a2f,
190     0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df, 0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea,
191     0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34, 0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b,
192     0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d, 0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413,
193     0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1, 0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6,
194     0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972, 0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85,
195     0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed, 0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511,
196     0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe, 0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b,
197     0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05, 0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1,
198     0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, 0x30101020, 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf,
199     0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3, 0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e,
200     0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a, 0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6,
201     0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3, 0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b,
202     0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428, 0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad,
203     0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14, 0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8,
204     0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4, 0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2,
205     0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda, 0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949,
206     0xb46c6cd8, 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf, 0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810,
207     0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c, 0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697,
208     0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e, 0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f,
209     0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc, 0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c,
210     0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969, 0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27,
211     0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122, 0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433,
212     0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9, 0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5,
213     0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, 0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0,
214     0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e, 0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c
215 };
216 
217 /*
218    Decryption table for LITTLE ENDIAN architecture.
219 
220    Lookup table for computing the InvMixColumns() Transformation with InvSubBytes applied to input
221    value S.  Each entry of this table represents
222    the result of {0e} dot S[x,c] | {09} dot S[x,c] | {0d} dot S[x,c] | {0b} dot S[x,c]. See Equation
223    5.10 on page 23 AES specification(Pub 197)
224 
225    The most significant byte is the result of {0e} dot S, and the least significant byte is the result
226    of {0b} dot S[x,c].
227  */
228 NX_CRYPTO_AES_TABLE ULONG aes_decryption_table[256] =
229 {
230     0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a, 0xcb6bab3b, 0xf1459d1f, 0xab58faac, 0x9303e34b,
231     0x55fa3020, 0xf66d76ad, 0x9176cc88, 0x254c02f5, 0xfcd7e54f, 0xd7cb2ac5, 0x80443526, 0x8fa362b5,
232     0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d, 0x02752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b,
233     0xe75f8f03, 0x959c9215, 0xeb7a6dbf, 0xda595295, 0x2d83bed4, 0xd3217458, 0x2969e049, 0x44c8c98e,
234     0x6a89c275, 0x78798ef4, 0x6b3e5899, 0xdd71b927, 0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d,
235     0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362, 0xe07764b1, 0x84ae6bbb, 0x1ca081fe, 0x942b08f9,
236     0x58684870, 0x19fd458f, 0x876cde94, 0xb7f87b52, 0x23d373ab, 0xe2024b72, 0x578f1fe3, 0x2aab5566,
237     0x0728ebb2, 0x03c2b52f, 0x9a7bc586, 0xa50837d3, 0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed,
238     0x2b1ccf8a, 0x92b479a7, 0xf0f207f3, 0xa1e2694e, 0xcdf4da65, 0xd5be0506, 0x1f6234d1, 0x8afea6c4,
239     0x9d532e34, 0xa055f3a2, 0x32e18a05, 0x75ebf6a4, 0x39ec830b, 0xaaef6040, 0x069f715e, 0x51106ebd,
240     0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d, 0xb58d5491, 0x055dc471, 0x6fd40604, 0xff155060,
241     0x24fb9819, 0x97e9bdd6, 0xcc434089, 0x779ed967, 0xbd42e8b0, 0x888b8907, 0x385b19e7, 0xdbeec879,
242     0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x00000000, 0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c,
243     0xfbff0efd, 0x5638850f, 0x1ed5ae3d, 0x27392d36, 0x64d90f0a, 0x21a65c68, 0xd1545b9b, 0x3a2e3624,
244     0xb1670a0c, 0x0fe75793, 0xd296eeb4, 0x9e919b1b, 0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c,
245     0x0aba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12, 0x0b0d090e, 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14,
246     0x8519f157, 0x4c0775af, 0xbbdd99ee, 0xfd607fa3, 0x9f2601f7, 0xbcf5725c, 0xc53b6644, 0x347efb5b,
247     0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8, 0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684,
248     0x7d244a85, 0xf83dbbd2, 0x1132f9ae, 0x6da129c7, 0x4b2f9e1d, 0xf330b2dc, 0xec52860d, 0xd0e3c177,
249     0x6c16b32b, 0x99b970a9, 0xfa489411, 0x2264e947, 0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322,
250     0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498, 0xcf81f5a6, 0x28de7aa5, 0x268eb7da, 0xa4bfad3f,
251     0xe49d3a2c, 0x0d927850, 0x9bcc5f6a, 0x62467e54, 0xc2138df6, 0xe8b8d890, 0x5ef7392e, 0xf5afc382,
252     0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf, 0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb,
253     0x097826cd, 0xf418596e, 0x01b79aec, 0xa89a4f83, 0x656e95e6, 0x7ee6ffaa, 0x08cfbc21, 0xe6e815ef,
254     0xd99be7ba, 0xce366f4a, 0xd4099fea, 0xd67cb029, 0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235,
255     0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733, 0x4a9804f1, 0xf7daec41, 0x0e50cd7f, 0x2ff69117,
256     0x8dd64d76, 0x4db0ef43, 0x544daacc, 0xdf0496e4, 0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, 0x7f516546,
257     0x04ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb, 0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d,
258     0x8c61d79a, 0x7a0ca137, 0x8e14f859, 0x893c13eb, 0xee27a9ce, 0x35c961b7, 0xede51ce1, 0x3cb1477a,
259     0x59dfd29c, 0x3f73f255, 0x79ce1418, 0xbf37c773, 0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478,
260     0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2, 0x72c31d16, 0x0c25e2bc, 0x8b493c28, 0x41950dff,
261     0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664, 0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0
262 };
263 
264 /*
265     Inverse Mix Table for LITTLE ENDIAN architecture.
266     Lookup table for computing the InvMixColumns() Transformation.  Each entry of this table represents
267     the result of {0e} dot S[x,c] | {09} dot S[x,c] | {0d} dot S[x,c] | {0b} dot S[x,c]. See Equation
268     5.10 on page 23 AES specification(Pub 197)
269 
270     The most significant byte is the result of {0e} dot S, and the least significant byte is the result
271     of {0b} dot S[x,c].
272  */
273 
274 NX_CRYPTO_AES_TABLE ULONG aes_inv_mix_table[256] =
275 {
276     0x00000000, 0x0b0d090e, 0x161a121c, 0x1d171b12, 0x2c342438, 0x27392d36, 0x3a2e3624, 0x31233f2a,
277     0x58684870, 0x5365417e, 0x4e725a6c, 0x457f5362, 0x745c6c48, 0x7f516546, 0x62467e54, 0x694b775a,
278     0xb0d090e0, 0xbbdd99ee, 0xa6ca82fc, 0xadc78bf2, 0x9ce4b4d8, 0x97e9bdd6, 0x8afea6c4, 0x81f3afca,
279     0xe8b8d890, 0xe3b5d19e, 0xfea2ca8c, 0xf5afc382, 0xc48cfca8, 0xcf81f5a6, 0xd296eeb4, 0xd99be7ba,
280     0x7bbb3bdb, 0x70b632d5, 0x6da129c7, 0x66ac20c9, 0x578f1fe3, 0x5c8216ed, 0x41950dff, 0x4a9804f1,
281     0x23d373ab, 0x28de7aa5, 0x35c961b7, 0x3ec468b9, 0x0fe75793, 0x04ea5e9d, 0x19fd458f, 0x12f04c81,
282     0xcb6bab3b, 0xc066a235, 0xdd71b927, 0xd67cb029, 0xe75f8f03, 0xec52860d, 0xf1459d1f, 0xfa489411,
283     0x9303e34b, 0x980eea45, 0x8519f157, 0x8e14f859, 0xbf37c773, 0xb43ace7d, 0xa92dd56f, 0xa220dc61,
284     0xf66d76ad, 0xfd607fa3, 0xe07764b1, 0xeb7a6dbf, 0xda595295, 0xd1545b9b, 0xcc434089, 0xc74e4987,
285     0xae053edd, 0xa50837d3, 0xb81f2cc1, 0xb31225cf, 0x82311ae5, 0x893c13eb, 0x942b08f9, 0x9f2601f7,
286     0x46bde64d, 0x4db0ef43, 0x50a7f451, 0x5baafd5f, 0x6a89c275, 0x6184cb7b, 0x7c93d069, 0x779ed967,
287     0x1ed5ae3d, 0x15d8a733, 0x08cfbc21, 0x03c2b52f, 0x32e18a05, 0x39ec830b, 0x24fb9819, 0x2ff69117,
288     0x8dd64d76, 0x86db4478, 0x9bcc5f6a, 0x90c15664, 0xa1e2694e, 0xaaef6040, 0xb7f87b52, 0xbcf5725c,
289     0xd5be0506, 0xdeb30c08, 0xc3a4171a, 0xc8a91e14, 0xf98a213e, 0xf2872830, 0xef903322, 0xe49d3a2c,
290     0x3d06dd96, 0x360bd498, 0x2b1ccf8a, 0x2011c684, 0x1132f9ae, 0x1a3ff0a0, 0x0728ebb2, 0x0c25e2bc,
291     0x656e95e6, 0x6e639ce8, 0x737487fa, 0x78798ef4, 0x495ab1de, 0x4257b8d0, 0x5f40a3c2, 0x544daacc,
292     0xf7daec41, 0xfcd7e54f, 0xe1c0fe5d, 0xeacdf753, 0xdbeec879, 0xd0e3c177, 0xcdf4da65, 0xc6f9d36b,
293     0xafb2a431, 0xa4bfad3f, 0xb9a8b62d, 0xb2a5bf23, 0x83868009, 0x888b8907, 0x959c9215, 0x9e919b1b,
294     0x470a7ca1, 0x4c0775af, 0x51106ebd, 0x5a1d67b3, 0x6b3e5899, 0x60335197, 0x7d244a85, 0x7629438b,
295     0x1f6234d1, 0x146f3ddf, 0x097826cd, 0x02752fc3, 0x335610e9, 0x385b19e7, 0x254c02f5, 0x2e410bfb,
296     0x8c61d79a, 0x876cde94, 0x9a7bc586, 0x9176cc88, 0xa055f3a2, 0xab58faac, 0xb64fe1be, 0xbd42e8b0,
297     0xd4099fea, 0xdf0496e4, 0xc2138df6, 0xc91e84f8, 0xf83dbbd2, 0xf330b2dc, 0xee27a9ce, 0xe52aa0c0,
298     0x3cb1477a, 0x37bc4e74, 0x2aab5566, 0x21a65c68, 0x10856342, 0x1b886a4c, 0x069f715e, 0x0d927850,
299     0x64d90f0a, 0x6fd40604, 0x72c31d16, 0x79ce1418, 0x48ed2b32, 0x43e0223c, 0x5ef7392e, 0x55fa3020,
300     0x01b79aec, 0x0aba93e2, 0x17ad88f0, 0x1ca081fe, 0x2d83bed4, 0x268eb7da, 0x3b99acc8, 0x3094a5c6,
301     0x59dfd29c, 0x52d2db92, 0x4fc5c080, 0x44c8c98e, 0x75ebf6a4, 0x7ee6ffaa, 0x63f1e4b8, 0x68fcedb6,
302     0xb1670a0c, 0xba6a0302, 0xa77d1810, 0xac70111e, 0x9d532e34, 0x965e273a, 0x8b493c28, 0x80443526,
303     0xe90f427c, 0xe2024b72, 0xff155060, 0xf418596e, 0xc53b6644, 0xce366f4a, 0xd3217458, 0xd82c7d56,
304     0x7a0ca137, 0x7101a839, 0x6c16b32b, 0x671bba25, 0x5638850f, 0x5d358c01, 0x40229713, 0x4b2f9e1d,
305     0x2264e947, 0x2969e049, 0x347efb5b, 0x3f73f255, 0x0e50cd7f, 0x055dc471, 0x184adf63, 0x1347d66d,
306     0xcadc31d7, 0xc1d138d9, 0xdcc623cb, 0xd7cb2ac5, 0xe6e815ef, 0xede51ce1, 0xf0f207f3, 0xfbff0efd,
307     0x92b479a7, 0x99b970a9, 0x84ae6bbb, 0x8fa362b5, 0xbe805d9f, 0xb58d5491, 0xa89a4f83, 0xa397468d
308 };
309 
310 
311 #endif
312 
313 /* S-Box.  Refer to figure 7 on page 16,  AES specification(Pub 197) */
314 NX_CRYPTO_AES_TABLE UCHAR sub_bytes_sbox[] =
315 {
316     0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
317     0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
318     0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
319     0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
320     0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
321     0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
322     0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
323     0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
324     0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
325     0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
326     0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
327     0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
328     0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
329     0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
330     0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
331     0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
332 };
333 
334 /* Inverse S-Box.  Refer to figure 14 on page 22,  AES specification(Pub 197) */
335 NX_CRYPTO_AES_TABLE UCHAR inverse_sub_bytes_sbox[] =
336 {
337     0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
338     0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
339     0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
340     0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
341     0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
342     0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
343     0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
344     0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
345     0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
346     0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
347     0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
348     0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
349     0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
350     0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
351     0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
352     0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
353 };
354 
355 
356 /* Rcon array, used for key expansion.  Refer to Appendix A on page 27,  AES specification(Pub 197) */
357 NX_CRYPTO_AES_TABLE UCHAR aes_rcon_array[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36};
358 
359 /* This array is generated using the nx_crypto_aes_multiply function, as powers of x in the
360    AES polynomial field. The array is shifted such that the indexes line up so that x**1 is
361    at index 1. The powers of x are cyclical, so the element at index 0 is actually x**255. */
362 /* For Little endian */
363 #ifdef NX_CRYPTO_LITTLE_ENDIAN
364 #define LEFT_ROTATE8(val)     (((val) >> 8) | ((val) << 24))
365 #define LEFT_ROTATE16(val)    (((val) >> 16) | ((val) << 16))
366 #define LEFT_ROTATE24(val)    (((val) >> 24) | ((val) << 8))
367 #define SET_MSB_BYTE(val)     ((UINT)(val))
368 #define SET_2ND_BYTE(val)     ((UINT)(val) << 8)
369 #define SET_3RD_BYTE(val)     ((UINT)(val) << 16)
370 #define SET_LSB_BYTE(val)     ((UINT)(val) << 24)
371 #define EXTRACT_MSB_BYTE(val) ((val) & 0xFF)
372 #define EXTRACT_2ND_BYTE(val) (((val) >> 8) & 0xFF)
373 #define EXTRACT_3RD_BYTE(val) (((val) >> 16) & 0xFF)
374 #define EXTRACT_LSB_BYTE(val) ((val) >> 24)
375 
376 #define SWAP_ENDIAN(val)      ((((val) & 0xFF000000) >> 24) | (((val) & 0x00FF0000) >> 8) | (((val) & 0x0000FF00) << 8) | (((val) & 0x000000FF) << 24))
377 
378 
379 
380 /* End of for little endian */
381 /* For Big Endian */
382 #else
383 #define LEFT_ROTATE8(val)     (((val) << 8) | ((val) >> 24))
384 #define LEFT_ROTATE16(val)    (((val) >> 16) | ((val) << 16))
385 #define LEFT_ROTATE24(val)    (((val) << 24) | ((val) >> 8))
386 
387 #define SET_MSB_BYTE(val)     ((val) << 24)
388 #define SET_2ND_BYTE(val)     ((val) << 16)
389 #define SET_3RD_BYTE(val)     ((val) << 8)
390 #define SET_LSB_BYTE(val)     ((UINT)(val))
391 #define EXTRACT_MSB_BYTE(val) ((val) >> 24)
392 #define EXTRACT_2ND_BYTE(val) (((val) >> 16) & 0xFF)
393 #define EXTRACT_3RD_BYTE(val) (((val) >> 8) & 0xFF)
394 #define EXTRACT_LSB_BYTE(val) ((val) & 0xFF)
395 
396 #endif
397 
398 #ifdef NX_CRYPTO_SELF_TEST
399 extern UINT _nx_crypto_library_state;
400 #endif /* NX_CRYPTO_SELF_TEST */
401 
402 /**************************************************************************/
403 /* Utility routines                                                       */
404 /**************************************************************************/
405 
406 
407 
408 /**************************************************************************/
409 /*                                                                        */
410 /*  FUNCTION                                               RELEASE        */
411 /*                                                                        */
412 /*    _nx_crypto_aes_add_round_key                        PORTABLE C      */
413 /*                                                           6.1.7        */
414 /*  AUTHOR                                                                */
415 /*                                                                        */
416 /*    Timothy Stapko, Microsoft Corporation                               */
417 /*                                                                        */
418 /*  DESCRIPTION                                                           */
419 /*                                                                        */
420 /*    This function implements AddRoundKey() function described in        */
421 /*    section 5.1.4 of the AES specification(Pub 197)                     */
422 /*                                                                        */
423 /*  INPUT                                                                 */
424 /*                                                                        */
425 /*    aes_ptr                               Pointer to AES control block  */
426 /*    round_key                             Pointer to key schedule       */
427 /*                                                                        */
428 /*  OUTPUT                                                                */
429 /*                                                                        */
430 /*    None                                                                */
431 /*                                                                        */
432 /*  CALLS                                                                 */
433 /*                                                                        */
434 /*    None                                                                */
435 /*                                                                        */
436 /*  CALLED BY                                                             */
437 /*                                                                        */
438 /*    _nx_crypto_aes_encrypt                Perform AES mode encryption   */
439 /*    _nx_crypto_aes_decrypt                Perform AES mode decryption   */
440 /*                                                                        */
441 /*  RELEASE HISTORY                                                       */
442 /*                                                                        */
443 /*    DATE              NAME                      DESCRIPTION             */
444 /*                                                                        */
445 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
446 /*  09-30-2020     Timothy Stapko           Modified comment(s), updated  */
447 /*                                            constants and conditionals, */
448 /*                                            resulting in version 6.1    */
449 /*  06-02-2021     Bhupendra Naphade        Modified comment(s),          */
450 /*                                            renamed FIPS symbol to      */
451 /*                                            self-test,                  */
452 /*                                            resulting in version 6.1.7  */
453 /*                                                                        */
454 /**************************************************************************/
_nx_crypto_aes_add_round_key(NX_CRYPTO_AES * aes_ptr,UINT * round_key)455 NX_CRYPTO_KEEP static VOID _nx_crypto_aes_add_round_key(NX_CRYPTO_AES *aes_ptr, UINT *round_key)
456 {
457 UINT i;
458 
459     for (i = 0; i < 4; ++i)
460     {
461         aes_ptr -> nx_crypto_aes_state[i] ^= round_key[i];
462     }
463 }
464 
465 
466 /**************************************************************************/
467 /* Encryption routines                                                    */
468 /**************************************************************************/
469 /**************************************************************************/
470 /*                                                                        */
471 /*  FUNCTION                                               RELEASE        */
472 /*                                                                        */
473 /*    _nx_crypto_aes_sub_shift_roundkey                   PORTABLE C      */
474 /*                                                           6.1          */
475 /*  AUTHOR                                                                */
476 /*                                                                        */
477 /*    Timothy Stapko, Microsoft Corporation                               */
478 /*                                                                        */
479 /*  DESCRIPTION                                                           */
480 /*                                                                        */
481 /*    This function combines the following operations:                    */
482 /*       SubBytes(state)                                                  */
483 /*       Shiftrows(state)                                                 */
484 /*       AddRoundKey(state, w[Nr*Nb, (Nr+1)*Nb-1])                        */
485 /*    Refer to Figure 5 on page 15 of the AES Specification (Pub 197)     */
486 /*                                                                        */
487 /*  INPUT                                                                 */
488 /*                                                                        */
489 /*    aes_ptr                               Pointer to AES control block  */
490 /*    round_key                             Pointer to round key          */
491 /*                                                                        */
492 /*  OUTPUT                                                                */
493 /*                                                                        */
494 /*    None                                                                */
495 /*                                                                        */
496 /*  CALLS                                                                 */
497 /*                                                                        */
498 /*    None                                                                */
499 /*                                                                        */
500 /*  CALLED BY                                                             */
501 /*                                                                        */
502 /*    _nx_crypto_aes_encrypt                Perform AES mode encryption   */
503 /*                                                                        */
504 /*  RELEASE HISTORY                                                       */
505 /*                                                                        */
506 /*    DATE              NAME                      DESCRIPTION             */
507 /*                                                                        */
508 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
509 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
510 /*                                            resulting in version 6.1    */
511 /*                                                                        */
512 /**************************************************************************/
_nx_crypto_aes_sub_shift_roundkey(NX_CRYPTO_AES * aes_ptr,UINT * round_key)513 NX_CRYPTO_KEEP static VOID _nx_crypto_aes_sub_shift_roundkey(NX_CRYPTO_AES *aes_ptr, UINT *round_key)
514 {
515 /*
516    S00    S04    S08    S12          S00    S04    S08    S12
517 
518    S01    S05    S09    S13          S05    S09    S13    S01
519                               --->
520    S02    S06    S10    S14          S10    S14    S02    S06
521 
522    S03    S07    S11    S15          S15    S03    S07    S11
523  */
524 
525 
526 UINT   S0, S1, S2, S3;
527 UCHAR *S;
528 
529     S = (UCHAR *)aes_ptr -> nx_crypto_aes_state;
530 
531     S0 = ((SET_MSB_BYTE(sub_bytes_sbox[S[0]])) |
532           (SET_2ND_BYTE(sub_bytes_sbox[S[5]])) |
533           (SET_3RD_BYTE(sub_bytes_sbox[S[10]])) |
534           (SET_LSB_BYTE(sub_bytes_sbox[S[15]]))) ^ round_key[0];
535 
536     S1 = ((SET_MSB_BYTE(sub_bytes_sbox[S[4]])) |
537           (SET_2ND_BYTE(sub_bytes_sbox[S[9]])) |
538           (SET_3RD_BYTE(sub_bytes_sbox[S[14]])) |
539           (SET_LSB_BYTE(sub_bytes_sbox[S[03]]))) ^ round_key[1];
540 
541     S2 = ((SET_MSB_BYTE(sub_bytes_sbox[S[8]])) |
542           (SET_2ND_BYTE(sub_bytes_sbox[S[13]])) |
543           (SET_3RD_BYTE(sub_bytes_sbox[S[02]])) |
544           (SET_LSB_BYTE(sub_bytes_sbox[S[07]]))) ^ round_key[2];
545 
546     S3 = ((SET_MSB_BYTE(sub_bytes_sbox[S[12]])) |
547           (SET_2ND_BYTE(sub_bytes_sbox[S[1]])) |
548           (SET_3RD_BYTE(sub_bytes_sbox[S[06]])) |
549           (SET_LSB_BYTE(sub_bytes_sbox[S[11]]))) ^ round_key[3];
550 
551     aes_ptr -> nx_crypto_aes_state[0] = S0;
552     aes_ptr -> nx_crypto_aes_state[1] = S1;
553     aes_ptr -> nx_crypto_aes_state[2] = S2;
554     aes_ptr -> nx_crypto_aes_state[3] = S3;
555 
556 #ifdef NX_SECURE_KEY_CLEAR
557     S0 = 0; S1 = 0; S2 = 0; S3 = 0;
558 #endif /* NX_SECURE_KEY_CLEAR  */
559 }
560 
561 /**************************************************************************/
562 /*                                                                        */
563 /*  FUNCTION                                               RELEASE        */
564 /*                                                                        */
565 /*    _nx_crypto_aes_inv_sub_shift_roundkey               PORTABLE C      */
566 /*                                                           6.1          */
567 /*  AUTHOR                                                                */
568 /*                                                                        */
569 /*    Timothy Stapko, Microsoft Corporation                               */
570 /*                                                                        */
571 /*  DESCRIPTION                                                           */
572 /*                                                                        */
573 /*    This function combines the following operations in EqInvCipher:     */
574 /*       InvSubBytes(state)                                               */
575 /*       InvShiftrows(state)                                              */
576 /*       AddRoundKey(state, dw[0, Nb-1])                                  */
577 /*    Refer to Figure 15 on page 25 of the AES Specification (Pub 197)    */
578 /*                                                                        */
579 /*  INPUT                                                                 */
580 /*                                                                        */
581 /*    aes_ptr                               Pointer to AES control block  */
582 /*    round_key                             Pointer to round key          */
583 /*                                                                        */
584 /*  OUTPUT                                                                */
585 /*                                                                        */
586 /*    None                                                                */
587 /*                                                                        */
588 /*  CALLS                                                                 */
589 /*                                                                        */
590 /*    None                                                                */
591 /*                                                                        */
592 /*  CALLED BY                                                             */
593 /*                                                                        */
594 /*    _nx_crypto_aes_decrypt                Perform AES mode decryption   */
595 /*                                                                        */
596 /*  RELEASE HISTORY                                                       */
597 /*                                                                        */
598 /*    DATE              NAME                      DESCRIPTION             */
599 /*                                                                        */
600 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
601 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
602 /*                                            resulting in version 6.1    */
603 /*                                                                        */
604 /**************************************************************************/
_nx_crypto_aes_inv_sub_shift_roundkey(NX_CRYPTO_AES * aes_ptr,UINT * round_key)605 NX_CRYPTO_KEEP static VOID _nx_crypto_aes_inv_sub_shift_roundkey(NX_CRYPTO_AES *aes_ptr, UINT *round_key)
606 {
607 /*
608    S00    S04    S08    S12          S00    S04    S08    S12
609 
610    S01    S05    S09    S13          S13    S01    S05    S09
611                               --->
612    S02    S06    S10    S14          S10    S14    S02    S06
613 
614    S03    S07    S11    S15          S07    S11    S15    S03
615  */
616 
617 
618 UINT   S0, S1, S2, S3;
619 UCHAR *S;
620 
621     S = (UCHAR *)aes_ptr -> nx_crypto_aes_state;
622 
623     S0 = ((SET_MSB_BYTE(inverse_sub_bytes_sbox[S[0]])) |
624           (SET_2ND_BYTE(inverse_sub_bytes_sbox[S[13]])) |
625           (SET_3RD_BYTE(inverse_sub_bytes_sbox[S[10]])) |
626           (SET_LSB_BYTE(inverse_sub_bytes_sbox[S[7]]))) ^ round_key[0];
627 
628     S1 = ((SET_MSB_BYTE(inverse_sub_bytes_sbox[S[4]])) |
629           (SET_2ND_BYTE(inverse_sub_bytes_sbox[S[1]])) |
630           (SET_3RD_BYTE(inverse_sub_bytes_sbox[S[14]])) |
631           (SET_LSB_BYTE(inverse_sub_bytes_sbox[S[11]]))) ^ round_key[1];
632 
633     S2 = ((SET_MSB_BYTE(inverse_sub_bytes_sbox[S[8]])) |
634           (SET_2ND_BYTE(inverse_sub_bytes_sbox[S[5]])) |
635           (SET_3RD_BYTE(inverse_sub_bytes_sbox[S[2]])) |
636           (SET_LSB_BYTE(inverse_sub_bytes_sbox[S[15]]))) ^ round_key[2];
637 
638     S3 = ((SET_MSB_BYTE(inverse_sub_bytes_sbox[S[12]])) |
639           (SET_2ND_BYTE(inverse_sub_bytes_sbox[S[9]])) |
640           (SET_3RD_BYTE(inverse_sub_bytes_sbox[S[6]])) |
641           (SET_LSB_BYTE(inverse_sub_bytes_sbox[S[3]]))) ^ round_key[3];
642 
643 
644     aes_ptr -> nx_crypto_aes_state[0] = S0;
645     aes_ptr -> nx_crypto_aes_state[1] = S1;
646     aes_ptr -> nx_crypto_aes_state[2] = S2;
647     aes_ptr -> nx_crypto_aes_state[3] = S3;
648 
649 #ifdef NX_SECURE_KEY_CLEAR
650     S0= 0; S1 = 0; S2 = 0; S3 = 0;
651 #endif /* NX_SECURE_KEY_CLEAR  */
652 }
653 
654 
655 /*
656 
657     __  __   __             __  __   __
658  | S0'|   | 02  03  01  01|  | S0  |
659  | S1'|   | 01  02  03  01|  | S1  |
660  | S2'| = | 01  01  02  03|  | S2  |
661  | S3'|   | 03  01  01  02|  | S3  |
662     --  --   --             --  --   --
663 
664     S' =    V0   ^    V1   ^     V2  ^    V3
665    S0' = {02}*S0 ^ {03}*S1 ^ {01}*S2 ^ {01}*S3
666    S1' = {01}*S0 ^ {02}*S1 ^ {03}*S2 ^ {01}*S3
667    S2' = {01}*S0 ^ {01}*S1 ^ {02}*S2 ^ {03}*S3
668    S3' = {03}*S0 ^ {01}*S1 ^ {01}*S2 ^ {02}*S3
669 
670 
671  */
672 
673 
674 /**************************************************************************/
675 /*                                                                        */
676 /*  FUNCTION                                               RELEASE        */
677 /*                                                                        */
678 /*    _nx_crypto_aes_encryption_round                     PORTABLE C      */
679 /*                                                           6.1          */
680 /*  AUTHOR                                                                */
681 /*                                                                        */
682 /*    Timothy Stapko, Microsoft Corporation                               */
683 /*                                                                        */
684 /*  DESCRIPTION                                                           */
685 /*                                                                        */
686 /*    This function combines the following operations:                    */
687 /*       SubBytes(state)                                                  */
688 /*       Shiftrows(state)                                                 */
689 /*       MixColumns(state)                                                */
690 /*       AddRoundKey(state, w[round*Nb, (round+1)*Nb-1])                  */
691 /*    This step is the body of the loop in the middle of Cipher.          */
692 /*    Refer to Figure 5 on page 15 of the AES Specification (Pub 197)     */
693 /*                                                                        */
694 /*  INPUT                                                                 */
695 /*                                                                        */
696 /*    aes_ptr                               Pointer to AES control block  */
697 /*    num_rounds                            Indicates total number of     */
698 /*                                            rounds for this operation.  */
699 /*                                                                        */
700 /*  OUTPUT                                                                */
701 /*                                                                        */
702 /*    None                                                                */
703 /*                                                                        */
704 /*  CALLS                                                                 */
705 /*                                                                        */
706 /*    None                                                                */
707 /*                                                                        */
708 /*  CALLED BY                                                             */
709 /*                                                                        */
710 /*    _nx_crypto_aes_encrypt                Perform AES mode encryption   */
711 /*                                                                        */
712 /*  RELEASE HISTORY                                                       */
713 /*                                                                        */
714 /*    DATE              NAME                      DESCRIPTION             */
715 /*                                                                        */
716 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
717 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
718 /*                                            resulting in version 6.1    */
719 /*                                                                        */
720 /**************************************************************************/
_nx_crypto_aes_encryption_round(NX_CRYPTO_AES * aes_ptr,int num_rounds)721 NX_CRYPTO_KEEP static VOID _nx_crypto_aes_encryption_round(NX_CRYPTO_AES *aes_ptr, int num_rounds)
722 {
723 UINT state_data[4];
724 UINT saved_state[4];
725 
726 int  round;
727 
728 
729     state_data[0] = aes_ptr -> nx_crypto_aes_state[0];
730     state_data[1] = aes_ptr -> nx_crypto_aes_state[1];
731     state_data[2] = aes_ptr -> nx_crypto_aes_state[2];
732     state_data[3] = aes_ptr -> nx_crypto_aes_state[3];
733 
734     for (round = 1; round < num_rounds; round++)
735     {
736         /* make a copy of the state data. */
737 
738         saved_state[0] = state_data[0];
739         saved_state[1] = state_data[1];
740         saved_state[2] = state_data[2];
741         saved_state[3] = state_data[3];
742 
743         /*
744            The MixColumns operates on the state after rotation.  The table below
745            illustrates the bytes before and after the ShiftRows operation.
746            This routine picks up bytes from its position BEFORE the rotation,
747            effectively combining SubBytes, ShiftRows, MixColumns, AddRoundKey
748            into one routine.
749 
750            S00    S04    S08    S12          S00    S04    S08    S12
751 
752            S01    S05    S09    S13          S05    S09    S13    S01
753                                       --->
754            S02    S06    S10    S14          S10    S14    S02    S06
755 
756            S03    S07    S11    S15          S15    S03    S07    S11
757 
758            The following code segment fully spells out the AES encryption, step by step.
759 
760 
761 
762            S = bytes[ 0];
763            V0 = aes_encryption_table[S];
764            S = bytes[ 5];
765            val = aes_encryption_table[S];
766            V1 = LEFT_ROTATE24(val);
767            S = bytes[10];
768            val = aes_encryption_table[S];
769            V2 = LEFT_ROTATE16(val);
770            S = bytes[15];
771            val = aes_encryption_table[S];
772            V3 = LEFT_ROTATE8(val);
773            temp_state[0] = V0 ^ V1 ^ V2 ^ V3 ^ (aes_ptr -> nx_crypto_aes_key_schedule[round * 4]);
774 
775            S = bytes[ 4];
776            V0 = aes_encryption_table[S];
777            S = bytes[ 9];
778            val = aes_encryption_table[S];
779            V1 = LEFT_ROTATE24(val);
780            S = bytes[14];
781            val = aes_encryption_table[S];
782            V2 = LEFT_ROTATE16(val);
783            S = bytes[ 3];
784            val = aes_encryption_table[S];
785            V3 = LEFT_ROTATE8(val);
786            temp_state[1] = V0 ^ V1 ^ V2 ^ V3 ^ (aes_ptr -> nx_crypto_aes_key_schedule[round * 4 + 1]);
787 
788 
789            S = bytes[ 8];
790            V0 = aes_encryption_table[S];
791            S = bytes[13];
792            val = aes_encryption_table[S];
793            V1 = LEFT_ROTATE24(val);
794            S = bytes[ 2];
795            val = aes_encryption_table[S];
796            V2 = LEFT_ROTATE16(val);
797            S = bytes[ 7];
798            val = aes_encryption_table[S];
799            V3 = LEFT_ROTATE8(val);
800            temp_state[2] = V0 ^ V1 ^ V2 ^ V3 ^ (aes_ptr -> nx_crypto_aes_key_schedule[round * 4 + 2]);
801 
802            S = bytes[12];
803            V0 = aes_encryption_table[S];
804            S = bytes[ 1];
805            val = aes_encryption_table[S];
806            V1 = LEFT_ROTATE24(val);
807            S = bytes[ 6];
808            val = aes_encryption_table[S];
809            V2 = LEFT_ROTATE16(val);
810            S = bytes[11];
811            val = aes_encryption_table[S];
812            V3 = LEFT_ROTATE8(val);
813            temp_state[3] = V0 ^ V1 ^ V2 ^ V3 ^ (aes_ptr -> nx_crypto_aes_key_schedule[round * 4 + 3]);
814 
815          */
816 
817         /* The following logic implements the steps above but could allow compiler to produce more
818            efficient code. */
819 
820         state_data[0] = aes_encryption_table[EXTRACT_MSB_BYTE(saved_state[0])] ^
821             (LEFT_ROTATE24(aes_encryption_table[EXTRACT_2ND_BYTE(saved_state[1])])) ^
822             (LEFT_ROTATE16(aes_encryption_table[EXTRACT_3RD_BYTE(saved_state[2])])) ^
823             (LEFT_ROTATE8(aes_encryption_table[EXTRACT_LSB_BYTE(saved_state[3])])) ^
824             (aes_ptr -> nx_crypto_aes_key_schedule[round * 4]);
825 
826         state_data[1] = aes_encryption_table[EXTRACT_MSB_BYTE(saved_state[1])] ^
827             (LEFT_ROTATE24(aes_encryption_table[EXTRACT_2ND_BYTE(saved_state[2])])) ^
828             (LEFT_ROTATE16(aes_encryption_table[EXTRACT_3RD_BYTE(saved_state[3])])) ^
829             (LEFT_ROTATE8(aes_encryption_table[EXTRACT_LSB_BYTE(saved_state[0])])) ^
830             (aes_ptr -> nx_crypto_aes_key_schedule[round * 4 + 1]);
831 
832         state_data[2] = aes_encryption_table[EXTRACT_MSB_BYTE(saved_state[2])] ^
833             (LEFT_ROTATE24(aes_encryption_table[EXTRACT_2ND_BYTE(saved_state[3])])) ^
834             (LEFT_ROTATE16(aes_encryption_table[EXTRACT_3RD_BYTE(saved_state[0])])) ^
835             (LEFT_ROTATE8(aes_encryption_table[EXTRACT_LSB_BYTE(saved_state[1])])) ^
836             (aes_ptr -> nx_crypto_aes_key_schedule[round * 4 + 2]);
837 
838         state_data[3] = aes_encryption_table[EXTRACT_MSB_BYTE(saved_state[3])] ^
839             (LEFT_ROTATE24(aes_encryption_table[EXTRACT_2ND_BYTE(saved_state[0])])) ^
840             (LEFT_ROTATE16(aes_encryption_table[EXTRACT_3RD_BYTE(saved_state[1])])) ^
841             (LEFT_ROTATE8(aes_encryption_table[EXTRACT_LSB_BYTE(saved_state[2])])) ^
842             (aes_ptr -> nx_crypto_aes_key_schedule[round * 4 + 3]);
843     }
844 
845     /* Write the data back to state structure. */
846     aes_ptr -> nx_crypto_aes_state[0] = state_data[0];
847     aes_ptr -> nx_crypto_aes_state[1] = state_data[1];
848     aes_ptr -> nx_crypto_aes_state[2] = state_data[2];
849     aes_ptr -> nx_crypto_aes_state[3] = state_data[3];
850 
851 #ifdef NX_SECURE_KEY_CLEAR
852     NX_CRYPTO_MEMSET(state_data, 0, sizeof(state_data));
853     NX_CRYPTO_MEMSET(saved_state, 0, sizeof(saved_state));
854 #endif /* NX_SECURE_KEY_CLEAR  */
855 }
856 
857 /**************************************************************************/
858 /*                                                                        */
859 /*  FUNCTION                                               RELEASE        */
860 /*                                                                        */
861 /*    _nx_crypto_aes_decryption_round                     PORTABLE C      */
862 /*                                                           6.1          */
863 /*  AUTHOR                                                                */
864 /*                                                                        */
865 /*    Timothy Stapko, Microsoft Corporation                               */
866 /*                                                                        */
867 /*  DESCRIPTION                                                           */
868 /*                                                                        */
869 /*    This function combines the following operations:                    */
870 /*       InvSubBytes(state)                                               */
871 /*       InvShiftrows(state)                                              */
872 /*       InvMixColumns(state)                                             */
873 /*       AddRoundKey(state, dw[round*Nb, (round+1)*Nb-1])                 */
874 /*    This step is the body of the loop in the middle of EqInvCipher.     */
875 /*    Refer to Figure 15 on page 25 of the AES Specification (Pub 197)    */
876 /*                                                                        */
877 /*  INPUT                                                                 */
878 /*                                                                        */
879 /*    aes_ptr                               Pointer to AES control block  */
880 /*    round                                 Indicates the number of       */
881 /*                                            rounds of this iteration.   */
882 /*                                                                        */
883 /*  OUTPUT                                                                */
884 /*                                                                        */
885 /*    None                                                                */
886 /*                                                                        */
887 /*  CALLS                                                                 */
888 /*                                                                        */
889 /*    None                                                                */
890 /*                                                                        */
891 /*  CALLED BY                                                             */
892 /*                                                                        */
893 /*    _nx_crypto_aes_decrypt                Perform AES mode decryption   */
894 /*                                                                        */
895 /*  RELEASE HISTORY                                                       */
896 /*                                                                        */
897 /*    DATE              NAME                      DESCRIPTION             */
898 /*                                                                        */
899 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
900 /*  09-30-2020     Timothy Stapko           Modified comment(s), updated  */
901 /*                                            constants, resulting        */
902 /*                                            in version 6.1              */
903 /*                                                                        */
904 /**************************************************************************/
_nx_crypto_aes_decryption_round(NX_CRYPTO_AES * aes_ptr,int round)905 NX_CRYPTO_KEEP static VOID _nx_crypto_aes_decryption_round(NX_CRYPTO_AES *aes_ptr, int round)
906 {
907 UINT   temp_state[4];
908 UCHAR *bytes = (UCHAR *)aes_ptr -> nx_crypto_aes_state;
909 UINT  *w = aes_ptr -> nx_crypto_aes_decrypt_key_schedule;
910 UINT   V0, V1, V2, V3;
911 
912 UCHAR  S;
913 ULONG  val;
914 
915 
916 /*
917    The InvMixColumns operates on the state after rotation.  The table below
918    illustrates the bytes before and after the InvShiftRows operation.
919    This routine picks up bytes from its position BEFORE the rotation,
920    effectively combining InvSubBytes, InvShiftRows, InvMixColumns, AddRoundKey
921    into one routine.
922 
923    S00    S04    S08    S12          S00    S04    S08    S12
924 
925    S01    S05    S09    S13          S13    S01    S05    S09
926                               --->
927    S02    S06    S10    S14          S10    S14    S02    S06
928 
929    S03    S07    S11    S15          S07    S11    S15    S03
930  */
931     S = bytes[0];
932     V0 = aes_decryption_table[S];
933     S = bytes[13];
934     val = aes_decryption_table[S];
935     V1 = LEFT_ROTATE24(val);
936     S = bytes[10];
937     val = aes_decryption_table[S];
938     V2 = LEFT_ROTATE16(val);
939     S = bytes[7];
940     val = aes_decryption_table[S];
941     V3 = LEFT_ROTATE8(val);
942     temp_state[0] = V0 ^ V1 ^ V2 ^ V3 ^ (w[round * 4]);
943 
944     S = bytes[4];
945     V0 = aes_decryption_table[S];
946     S = bytes[1];
947     val = aes_decryption_table[S];
948     V1 = LEFT_ROTATE24(val);
949     S = bytes[14];
950     val = aes_decryption_table[S];
951     V2 = LEFT_ROTATE16(val);
952     S = bytes[11];
953     val = aes_decryption_table[S];
954     V3 = LEFT_ROTATE8(val);
955     temp_state[1] = V0 ^ V1 ^ V2 ^ V3 ^ (w[round * 4 + 1]);
956 
957     S = bytes[8];
958     V0 = aes_decryption_table[S];
959     S = bytes[5];
960     val = aes_decryption_table[S];
961     V1 = LEFT_ROTATE24(val);
962     S = bytes[2];
963     val = aes_decryption_table[S];
964     V2 = LEFT_ROTATE16(val);
965     S = bytes[15];
966     val = aes_decryption_table[S];
967     V3 = LEFT_ROTATE8(val);
968     temp_state[2] = V0 ^ V1 ^ V2 ^ V3 ^ (w[round * 4 + 2]);
969 
970     S = bytes[12];
971     V0 = aes_decryption_table[S];
972     S = bytes[9];
973     val = aes_decryption_table[S];
974     V1 = LEFT_ROTATE24(val);
975     S = bytes[6];
976     val = aes_decryption_table[S];
977     V2 = LEFT_ROTATE16(val);
978     S = bytes[3];
979     val = aes_decryption_table[S];
980     V3 = LEFT_ROTATE8(val);
981     temp_state[3] = V0 ^ V1 ^ V2 ^ V3 ^ (w[round * 4 + 3]);
982 
983     aes_ptr -> nx_crypto_aes_state[0] = temp_state[0];
984     aes_ptr -> nx_crypto_aes_state[1] = temp_state[1];
985     aes_ptr -> nx_crypto_aes_state[2] = temp_state[2];
986     aes_ptr -> nx_crypto_aes_state[3] = temp_state[3];
987 
988 #ifdef NX_SECURE_KEY_CLEAR
989     NX_CRYPTO_MEMSET(temp_state, 0, sizeof(temp_state));
990 #endif /* NX_SECURE_KEY_CLEAR  */
991 }
992 
993 
994 /**************************************************************************/
995 /*                                                                        */
996 /*  FUNCTION                                               RELEASE        */
997 /*                                                                        */
998 /*    _nx_crypto_aes_encrypt                              PORTABLE C      */
999 /*                                                           6.1          */
1000 /*  AUTHOR                                                                */
1001 /*                                                                        */
1002 /*    Timothy Stapko, Microsoft Corporation                               */
1003 /*                                                                        */
1004 /*  DESCRIPTION                                                           */
1005 /*                                                                        */
1006 /*    This function performs AES encryption on a block of 16 byte message */
1007 /*    pointed to by "input", and the encrypted text is stored in buffer   */
1008 /*    pointed to by "output".  The size of the output buffer must be at   */
1009 /*    least 16 bytes.  The output buffer may point to the same input      */
1010 /*    buffer, in which case the encrypted text overwrites the input       */
1011 /*    message.                                                            */
1012 /*                                                                        */
1013 /*  INPUT                                                                 */
1014 /*                                                                        */
1015 /*    aes_ptr                               Pointer to AES control block  */
1016 /*    input                                 Pointer to an input message   */
1017 /*                                            of 16 bytes.                */
1018 /*    output                                Pointer to an output buffer   */
1019 /*                                            for storing the encrypted   */
1020 /*                                            message.  The output buffer */
1021 /*                                            must be at least 16 bytes.  */
1022 /*    length                                The length of output buffer   */
1023 /*                                                                        */
1024 /*  OUTPUT                                                                */
1025 /*                                                                        */
1026 /*    status                                Completion status             */
1027 /*                                                                        */
1028 /*  CALLS                                                                 */
1029 /*                                                                        */
1030 /*    _nx_seucre_aes_add_round_key          Perform AddRoundKey operation */
1031 /*    _nx_crypto_aes_encryption_round       The main body of AES          */
1032 /*                                            encryption                  */
1033 /*    _nx_crypto_aes_sub_shift_roundkey     Perform the last step in AES  */
1034 /*                                            encryption operation        */
1035 /*                                                                        */
1036 /*  CALLED BY                                                             */
1037 /*                                                                        */
1038 /*    Application Code                                                    */
1039 /*                                                                        */
1040 /*  RELEASE HISTORY                                                       */
1041 /*                                                                        */
1042 /*    DATE              NAME                      DESCRIPTION             */
1043 /*                                                                        */
1044 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
1045 /*  09-30-2020     Timothy Stapko           Modified comment(s), disabled */
1046 /*                                            unaligned access by default,*/
1047 /*                                            resulting in version 6.1    */
1048 /*                                                                        */
1049 /**************************************************************************/
_nx_crypto_aes_encrypt(NX_CRYPTO_AES * aes_ptr,UCHAR * input,UCHAR * output,UINT length)1050 NX_CRYPTO_KEEP UINT _nx_crypto_aes_encrypt(NX_CRYPTO_AES *aes_ptr, UCHAR *input, UCHAR *output, UINT length)
1051 {
1052 UINT  num_rounds;
1053 UINT *w;
1054 #ifndef NX_CRYPTO_ENABLE_UNALIGNED_ACCESS
1055 UCHAR *aes_state;
1056 #else
1057 UINT *buf;
1058 #endif
1059 
1060 
1061     NX_CRYPTO_PARAMETER_NOT_USED(length);
1062 
1063     w = aes_ptr -> nx_crypto_aes_key_schedule;
1064 
1065     num_rounds = aes_ptr -> nx_crypto_aes_rounds;
1066 
1067     if (num_rounds < 10 || num_rounds > 14)
1068     {
1069         return(NX_CRYPTO_INVALID_PARAMETER);
1070     }
1071 
1072 #ifndef NX_CRYPTO_ENABLE_UNALIGNED_ACCESS
1073     aes_state = (UCHAR *)aes_ptr -> nx_crypto_aes_state;
1074     aes_state[0] = input[0];
1075     aes_state[1] = input[1];
1076     aes_state[2] = input[2];
1077     aes_state[3] = input[3];
1078     aes_state[4] = input[4];
1079     aes_state[5] = input[5];
1080     aes_state[6] = input[6];
1081     aes_state[7] = input[7];
1082     aes_state[8] = input[8];
1083     aes_state[9] = input[9];
1084     aes_state[10] = input[10];
1085     aes_state[11] = input[11];
1086     aes_state[12] = input[12];
1087     aes_state[13] = input[13];
1088     aes_state[14] = input[14];
1089     aes_state[15] = input[15];
1090 #else
1091     buf = (UINT *)input;
1092     aes_ptr -> nx_crypto_aes_state[0] = buf[0];
1093     aes_ptr -> nx_crypto_aes_state[1] = buf[1];
1094     aes_ptr -> nx_crypto_aes_state[2] = buf[2];
1095     aes_ptr -> nx_crypto_aes_state[3] = buf[3];
1096 #endif
1097 
1098     _nx_crypto_aes_add_round_key(aes_ptr, &w[0]);
1099 
1100     _nx_crypto_aes_encryption_round(aes_ptr, (INT)num_rounds);
1101 
1102     _nx_crypto_aes_sub_shift_roundkey(aes_ptr, &w[num_rounds * 4]);
1103 
1104 
1105 #ifndef NX_CRYPTO_ENABLE_UNALIGNED_ACCESS
1106     output[0] = aes_state[0];
1107     output[1] = aes_state[1];
1108     output[2] = aes_state[2];
1109     output[3] = aes_state[3];
1110     output[4] = aes_state[4];
1111     output[5] = aes_state[5];
1112     output[6] = aes_state[6];
1113     output[7] = aes_state[7];
1114     output[8] = aes_state[8];
1115     output[9] = aes_state[9];
1116     output[10] = aes_state[10];
1117     output[11] = aes_state[11];
1118     output[12] = aes_state[12];
1119     output[13] = aes_state[13];
1120     output[14] = aes_state[14];
1121     output[15] = aes_state[15];
1122 #else
1123     buf = (UINT *)output;
1124     buf[0] = aes_ptr -> nx_crypto_aes_state[0];
1125     buf[1] = aes_ptr -> nx_crypto_aes_state[1];
1126     buf[2] = aes_ptr -> nx_crypto_aes_state[2];
1127     buf[3] = aes_ptr -> nx_crypto_aes_state[3];
1128 #endif
1129 
1130     return(NX_CRYPTO_SUCCESS);
1131 }
1132 
1133 
1134 /**************************************************************************/
1135 /* Key expansion routines                                                 */
1136 /**************************************************************************/
1137 /**************************************************************************/
1138 /*                                                                        */
1139 /*  FUNCTION                                               RELEASE        */
1140 /*                                                                        */
1141 /*    _nx_crypto_aes_subword                              PORTABLE C      */
1142 /*                                                           6.1          */
1143 /*  AUTHOR                                                                */
1144 /*                                                                        */
1145 /*    Timothy Stapko, Microsoft Corporation                               */
1146 /*                                                                        */
1147 /*  DESCRIPTION                                                           */
1148 /*                                                                        */
1149 /*    This function performs SubBytes(state) operation according to       */
1150 /*    section 5.1.1 on page 15 of the AES specification (Pub 197)         */
1151 /*                                                                        */
1152 /*  INPUT                                                                 */
1153 /*                                                                        */
1154 /*   word                                   The input 4-byte word         */
1155 /*                                                                        */
1156 /*  OUTPUT                                                                */
1157 /*                                                                        */
1158 /*   UINT word                              The value after being         */
1159 /*                                            substituted.                */
1160 /*                                                                        */
1161 /*  CALLS                                                                 */
1162 /*                                                                        */
1163 /*    None                                                                */
1164 /*                                                                        */
1165 /*  CALLED BY                                                             */
1166 /*                                                                        */
1167 /*    _nx_crypto_aes_key_expansion          AES key expansion             */
1168 /*                                                                        */
1169 /*  RELEASE HISTORY                                                       */
1170 /*                                                                        */
1171 /*    DATE              NAME                      DESCRIPTION             */
1172 /*                                                                        */
1173 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
1174 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
1175 /*                                            resulting in version 6.1    */
1176 /*                                                                        */
1177 /**************************************************************************/
_nx_crypto_aes_subword(UINT word)1178 NX_CRYPTO_KEEP static UINT _nx_crypto_aes_subword(UINT word)
1179 {
1180 UINT result;
1181 
1182     result = sub_bytes_sbox[word & 0xFF];
1183     result |= (UINT)((sub_bytes_sbox[(word & 0x0000FF00) >>  8]) <<  8);
1184     result |= (UINT)((sub_bytes_sbox[(word & 0x00FF0000) >> 16]) << 16);
1185     result |= (UINT)((sub_bytes_sbox[(word & 0xFF000000) >> 24]) << 24);
1186     return result;
1187 }
1188 
1189 /**************************************************************************/
1190 /*                                                                        */
1191 /*  FUNCTION                                               RELEASE        */
1192 /*                                                                        */
1193 /*    _nx_crypto_aes_key_expansion                        PORTABLE C      */
1194 /*                                                           6.1          */
1195 /*  AUTHOR                                                                */
1196 /*                                                                        */
1197 /*    Timothy Stapko, Microsoft Corporation                               */
1198 /*                                                                        */
1199 /*  DESCRIPTION                                                           */
1200 /*                                                                        */
1201 /*    This routine performs AES Key Expansion as outlined in seciton 5.2  */
1202 /*    on page 195 of the AES specification (Pub 197)                      */
1203 /*                                                                        */
1204 /*  INPUT                                                                 */
1205 /*                                                                        */
1206 /*    aes_ptr                               Pointer to AES control block  */
1207 /*                                                                        */
1208 /*  OUTPUT                                                                */
1209 /*                                                                        */
1210 /*    None                                                                */
1211 /*                                                                        */
1212 /*  CALLS                                                                 */
1213 /*                                                                        */
1214 /*    _nx_crypto_aes_subword                Apply sbox substitution       */
1215 /*                                                                        */
1216 /*  CALLED BY                                                             */
1217 /*                                                                        */
1218 /*    _nx_crypto_aes_key_set                Set AES crypto key            */
1219 /*                                                                        */
1220 /*  RELEASE HISTORY                                                       */
1221 /*                                                                        */
1222 /*    DATE              NAME                      DESCRIPTION             */
1223 /*                                                                        */
1224 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
1225 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
1226 /*                                            resulting in version 6.1    */
1227 /*                                                                        */
1228 /**************************************************************************/
_nx_crypto_aes_key_expansion(NX_CRYPTO_AES * aes_ptr)1229 NX_CRYPTO_KEEP static VOID _nx_crypto_aes_key_expansion(NX_CRYPTO_AES *aes_ptr)
1230 {
1231 UINT  temp;
1232 UINT  i;
1233 UINT  iterations = 0;
1234 UINT  loop_count;
1235 UINT *expanded_key;
1236 UINT  key_size;
1237 
1238     expanded_key = aes_ptr -> nx_crypto_aes_key_schedule;
1239 
1240     key_size = aes_ptr -> nx_crypto_aes_key_size;
1241 
1242     switch (key_size)
1243     {
1244     case NX_CRYPTO_AES_KEY_SIZE_128_BITS:
1245         iterations = 9;
1246         break;
1247     case NX_CRYPTO_AES_KEY_SIZE_192_BITS:
1248         iterations = 7;
1249         break;
1250 
1251     /* case NX_CRYPTO_AES_KEY_SIZE_256_BITS: */
1252     default:
1253         iterations = 6;
1254         break;
1255     }
1256 
1257     temp = expanded_key[key_size - 1];
1258     /* Expand the key schedule from the initial key. */
1259     i = key_size;
1260     for (loop_count = 0; loop_count < iterations; loop_count++)
1261     {
1262 
1263         temp = LEFT_ROTATE8(temp);                              /* (temp << 8) | (temp >> 24); */
1264         temp = _nx_crypto_aes_subword(temp);
1265         temp ^= SET_MSB_BYTE((UINT)aes_rcon_array[loop_count]); /* (((UINT)aes_rcon_array[loop_count]) << 24); */
1266         temp = expanded_key[i - key_size] ^ temp; expanded_key[i] = temp; i++;
1267         switch (key_size)
1268         {
1269         case NX_CRYPTO_AES_KEY_SIZE_256_BITS:
1270             temp = expanded_key[i - key_size] ^ temp; expanded_key[i] = temp; i++;
1271             temp = expanded_key[i - key_size] ^ temp; expanded_key[i] = temp; i++;
1272         /* AES KEY 256 bits: fall through the rest of the statement to complete
1273            one iteration of key expansion. */ /* fallthrough */
1274         case NX_CRYPTO_AES_KEY_SIZE_192_BITS:
1275             temp = expanded_key[i - key_size] ^ temp; expanded_key[i] = temp; i++;
1276 
1277             /* Special case for AES 256: Need an extra subword operation on 4th step. */
1278             if (key_size == NX_CRYPTO_AES_KEY_SIZE_256_BITS)
1279             {
1280                 temp = _nx_crypto_aes_subword(temp);
1281             }
1282             temp = expanded_key[i - key_size] ^ temp; expanded_key[i] = temp; i++;
1283         /* AES KEY 256 and 192 bits: fall through the rest of the statement to complete
1284            one iteration of key expansion. */ /* fallthrough */
1285         /* case NX_CRYPTO_AES_KEY_SIZE_128_BITS: */
1286         default:
1287             temp = expanded_key[i - key_size] ^ temp; expanded_key[i] = temp; i++;
1288             temp = expanded_key[i - key_size] ^ temp; expanded_key[i] = temp; i++;
1289             temp = expanded_key[i - key_size] ^ temp; expanded_key[i] = temp; i++;
1290             break;
1291         }
1292     }
1293     /* Last round. */
1294     temp = LEFT_ROTATE8(temp);                              /* (temp << 8) | (temp >> 24); */
1295     temp = _nx_crypto_aes_subword(temp);
1296     temp ^= SET_MSB_BYTE((UINT)aes_rcon_array[loop_count]); /* (((UINT)aes_rcon_array[loop_count]) << 24); */
1297     temp = expanded_key[i - key_size] ^ temp; expanded_key[i] = temp; i++;
1298     temp = expanded_key[i - key_size] ^ temp; expanded_key[i] = temp; i++;
1299     temp = expanded_key[i - key_size] ^ temp; expanded_key[i] = temp; i++;
1300     temp = expanded_key[i - key_size] ^ temp; expanded_key[i] = temp; i++;
1301 
1302 #ifdef NX_SECURE_KEY_CLEAR
1303     temp = 0;
1304 #endif /* NX_SECURE_KEY_CLEAR  */
1305 
1306     return;
1307 }
1308 
1309 /**************************************************************************/
1310 /*                                                                        */
1311 /*  FUNCTION                                               RELEASE        */
1312 /*                                                                        */
1313 /*    _nx_crypto_aes_key_expansion_inverse                PORTABLE C      */
1314 /*                                                           6.1.10       */
1315 /*  AUTHOR                                                                */
1316 /*                                                                        */
1317 /*    Timothy Stapko, Microsoft Corporation                               */
1318 /*                                                                        */
1319 /*  DESCRIPTION                                                           */
1320 /*                                                                        */
1321 /*    This routine performs AES Key Expansion as outlined in seciton 5.2  */
1322 /*    on page 195 of the AES specification (Pub 197)                      */
1323 /*                                                                        */
1324 /*    Note on the decryption side, NetX Crypto AES uses Equivalent        */
1325 /*    Inverse Cipher (section 5.3.5 in Pub 197).  Therefore the inverse   */
1326 /*    key expansion starts with the regular key expansion then apply      */
1327 /*    InvMixClumns(state). (Page 24 Pub 197).                             */
1328 /*                                                                        */
1329 /*  INPUT                                                                 */
1330 /*                                                                        */
1331 /*    aes_ptr                               Pointer to AES control block  */
1332 /*                                                                        */
1333 /*  OUTPUT                                                                */
1334 /*                                                                        */
1335 /*    None                                                                */
1336 /*                                                                        */
1337 /*  CALLS                                                                 */
1338 /*                                                                        */
1339 /*    None                                                                */
1340 /*                                                                        */
1341 /*  CALLED BY                                                             */
1342 /*                                                                        */
1343 /*    _nx_crypto_aes_key_set                Set AES crypto key            */
1344 /*                                                                        */
1345 /*  RELEASE HISTORY                                                       */
1346 /*                                                                        */
1347 /*    DATE              NAME                      DESCRIPTION             */
1348 /*                                                                        */
1349 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
1350 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
1351 /*                                            resulting in version 6.1    */
1352 /*  01-31-2022     Timothy Stapko           Modified comment(s),          */
1353 /*                                            moved inverse key expansion,*/
1354 /*                                            resulting in version 6.1.10 */
1355 /*                                                                        */
1356 /**************************************************************************/
_nx_crypto_aes_key_expansion_inverse(NX_CRYPTO_AES * aes_ptr)1357 NX_CRYPTO_KEEP static VOID _nx_crypto_aes_key_expansion_inverse(NX_CRYPTO_AES *aes_ptr)
1358 {
1359 UINT  i;
1360 UINT  num_rounds;
1361 UINT *expanded_key;
1362 UINT  V0, V1, V2, V3;
1363 
1364 UCHAR S;
1365 ULONG val;
1366 ULONG key;
1367 
1368     expanded_key = aes_ptr -> nx_crypto_aes_decrypt_key_schedule;
1369 
1370     num_rounds = aes_ptr -> nx_crypto_aes_rounds;
1371 
1372     /* Copy the 1st set of keys */
1373     for (i = 0; i < 4; i++)
1374     {
1375         aes_ptr -> nx_crypto_aes_decrypt_key_schedule[i] = aes_ptr -> nx_crypto_aes_key_schedule[i];
1376     }
1377 
1378     for (; i < 4 * (num_rounds); i++)
1379     {
1380 
1381         /* Pick up the key value from key_schedule[]. */
1382         key = aes_ptr -> nx_crypto_aes_key_schedule[i];
1383         S = EXTRACT_MSB_BYTE(key); /* (key >> 24) & 0xFF; */
1384 
1385         /* Performs InvMixColumns() operation by using the look up table. */
1386         V0 = aes_inv_mix_table[S];
1387 
1388         S = EXTRACT_2ND_BYTE(key);        /* (key >> 16) & 0xFF; */
1389         val = aes_inv_mix_table[S];
1390         V1 = LEFT_ROTATE24(val);          /* (val >> 8) | (val << 24); */
1391 
1392         S = EXTRACT_3RD_BYTE(key);        /* (key >>  8) & 0xFF;*/
1393         val = aes_inv_mix_table[S];
1394         V2 = LEFT_ROTATE16(val);          /* (val >> 16) | (val << 16); */
1395 
1396         S = (UCHAR)EXTRACT_LSB_BYTE(key); /* key & 0xFF; */
1397         val = aes_inv_mix_table[S];
1398         V3 = LEFT_ROTATE8(val);           /* (val >> 24) | (val << 8);*/
1399 
1400         /* Put values together */
1401         key =  V0 ^ V1 ^ V2 ^ V3;
1402 
1403         /* Stores the expanded key (after applying InvMixColumns()) */
1404         expanded_key[i] = key;
1405     }
1406 
1407     /* No need to perform InvMixColums() on the last 4 words. */
1408     expanded_key[i]     = aes_ptr -> nx_crypto_aes_key_schedule[i];
1409     expanded_key[i + 1] = aes_ptr -> nx_crypto_aes_key_schedule[i + 1];
1410     expanded_key[i + 2] = aes_ptr -> nx_crypto_aes_key_schedule[i + 2];
1411     expanded_key[i + 3] = aes_ptr -> nx_crypto_aes_key_schedule[i + 3];
1412 
1413     /* Set the inverse key expansion flag. */
1414     aes_ptr -> nx_crypto_aes_inverse_key_expanded = 1;
1415 
1416 #ifdef NX_SECURE_KEY_CLEAR
1417     key = 0;
1418 #endif /* NX_SECURE_KEY_CLEAR  */
1419 
1420     return;
1421 }
1422 
1423 
1424 /**************************************************************************/
1425 /* Decryption routines                                                    */
1426 /**************************************************************************/
1427 
1428 
1429 
1430 
1431 /*
1432 
1433     __  __   __             __  __   __
1434  | S0'|   | 0e  0b  0d  09|  | S0  |
1435  | S1'|   | 09  0e  0b  0d|  | S1  |
1436  | S2'| = | 0d  09  0e  0b|  | S2  |
1437  | S3'|   | 0b  0d  09  0e|  | S3  |
1438     --  --   --             --  --   --
1439 
1440     S' =    V0   ^    V1   ^     V2  ^    V3
1441    S0' = {0e}*S0 ^ {0b}*S1 ^ {0d}*S2 ^ {09}*S3
1442    S1' = {09}*S0 ^ {0e}*S1 ^ {0b}*S2 ^ {0d}*S3
1443    S2' = {0d}*S0 ^ {09}*S1 ^ {0e}*S2 ^ {0b}*S3
1444    S3' = {0b}*S0 ^ {0d}*S1 ^ {09}*S2 ^ {0e}*S3
1445 
1446 
1447  */
1448 
1449 
1450 /**************************************************************************/
1451 /*                                                                        */
1452 /*  FUNCTION                                               RELEASE        */
1453 /*                                                                        */
1454 /*    _nx_crypto_aes_decrypt                              PORTABLE C      */
1455 /*                                                           6.1.10       */
1456 /*  AUTHOR                                                                */
1457 /*                                                                        */
1458 /*    Timothy Stapko, Microsoft Corporation                               */
1459 /*                                                                        */
1460 /*  DESCRIPTION                                                           */
1461 /*                                                                        */
1462 /*    This function performs AES decryption on a block of 16 byte message */
1463 /*    pointed to by "input", and the decrypted text is stored in buffer   */
1464 /*    pointed to by "output".  The size of the output buffer must be at   */
1465 /*    least 16 bytes.  The output buffer may point to the same input      */
1466 /*    buffer, in which case the decrypted text overwrites the input       */
1467 /*    message.                                                            */
1468 /*                                                                        */
1469 /*  INPUT                                                                 */
1470 /*                                                                        */
1471 /*    aes_ptr                               Pointer to AES control block  */
1472 /*    input                                 Pointer to an input message   */
1473 /*                                            of 16 bytes.                */
1474 /*    output                                Pointer to an output buffer   */
1475 /*                                            for storing the decrypted   */
1476 /*                                            message.  The output buffer */
1477 /*                                            must be at least 16 bytes.  */
1478 /*    length                                The length of output buffer   */
1479 /*                                                                        */
1480 /*  OUTPUT                                                                */
1481 /*                                                                        */
1482 /*    status                                Completion status             */
1483 /*                                                                        */
1484 /*  CALLS                                                                 */
1485 /*                                                                        */
1486 /*    _nx_seucre_aes_add_round_key          Perform AddRoundKey operation */
1487 /*    _nx_crypto_aes_decryption_round       The main body of AES          */
1488 /*                                            decryption                  */
1489 /*    _nx_crypto_aes_inv_sub_shift_roundkey Perform the last step in AES  */
1490 /*                                            decryption operation        */
1491 /*                                                                        */
1492 /*  CALLED BY                                                             */
1493 /*                                                                        */
1494 /*    Application Code                                                    */
1495 /*                                                                        */
1496 /*  RELEASE HISTORY                                                       */
1497 /*                                                                        */
1498 /*    DATE              NAME                      DESCRIPTION             */
1499 /*                                                                        */
1500 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
1501 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
1502 /*                                            resulting in version 6.1    */
1503 /*  01-31-2022     Timothy Stapko           Modified comment(s),          */
1504 /*                                            moved inverse key expansion,*/
1505 /*                                            resulting in version 6.1.10 */
1506 /*                                                                        */
1507 /**************************************************************************/
_nx_crypto_aes_decrypt(NX_CRYPTO_AES * aes_ptr,UCHAR * input,UCHAR * output,UINT length)1508 NX_CRYPTO_KEEP UINT _nx_crypto_aes_decrypt(NX_CRYPTO_AES *aes_ptr, UCHAR *input, UCHAR *output, UINT length)
1509 {
1510 UINT  num_rounds;
1511 UINT  round;
1512 UINT *w;
1513 UINT *v;
1514 #ifndef NX_CRYPTO_ENABLE_UNALIGNED_ACCESS
1515 UCHAR *aes_state;
1516 #else
1517 UINT *buf;
1518 #endif
1519 
1520 
1521     NX_CRYPTO_PARAMETER_NOT_USED(length);
1522 
1523     /* If the flag is not set, we assume the inverse key expansion
1524        table is not created yet. Call the routine to create one. */
1525     if(aes_ptr -> nx_crypto_aes_inverse_key_expanded == 0)
1526     {
1527         _nx_crypto_aes_key_expansion_inverse(aes_ptr);
1528     }
1529 
1530 
1531     w = aes_ptr -> nx_crypto_aes_decrypt_key_schedule;
1532     v = aes_ptr -> nx_crypto_aes_key_schedule;
1533 
1534 #ifndef NX_CRYPTO_ENABLE_UNALIGNED_ACCESS
1535     aes_state = (UCHAR *)aes_ptr -> nx_crypto_aes_state;
1536     aes_state[0] = input[0];
1537     aes_state[1] = input[1];
1538     aes_state[2] = input[2];
1539     aes_state[3] = input[3];
1540     aes_state[4] = input[4];
1541     aes_state[5] = input[5];
1542     aes_state[6] = input[6];
1543     aes_state[7] = input[7];
1544     aes_state[8] = input[8];
1545     aes_state[9] = input[9];
1546     aes_state[10] = input[10];
1547     aes_state[11] = input[11];
1548     aes_state[12] = input[12];
1549     aes_state[13] = input[13];
1550     aes_state[14] = input[14];
1551     aes_state[15] = input[15];
1552 #else
1553     buf = (UINT *)input;
1554     aes_ptr -> nx_crypto_aes_state[0] = buf[0];
1555     aes_ptr -> nx_crypto_aes_state[1] = buf[1];
1556     aes_ptr -> nx_crypto_aes_state[2] = buf[2];
1557     aes_ptr -> nx_crypto_aes_state[3] = buf[3];
1558 #endif
1559 
1560 
1561     num_rounds = aes_ptr -> nx_crypto_aes_rounds;
1562 
1563     if (num_rounds < 10 || num_rounds > 14)
1564     {
1565         return(NX_CRYPTO_INVALID_PARAMETER);
1566     }
1567 
1568     _nx_crypto_aes_add_round_key(aes_ptr, &v[num_rounds * 4]);
1569 
1570     for (round = num_rounds - 1; round >= 1; --round)
1571     {
1572 
1573         _nx_crypto_aes_decryption_round(aes_ptr, (INT)round);
1574     }
1575 
1576     _nx_crypto_aes_inv_sub_shift_roundkey(aes_ptr, &w[0]);
1577 
1578     /* Extract the output encrypted block. */
1579 #ifndef NX_CRYPTO_ENABLE_UNALIGNED_ACCESS
1580     output[0] = aes_state[0];
1581     output[1] = aes_state[1];
1582     output[2] = aes_state[2];
1583     output[3] = aes_state[3];
1584     output[4] = aes_state[4];
1585     output[5] = aes_state[5];
1586     output[6] = aes_state[6];
1587     output[7] = aes_state[7];
1588     output[8] = aes_state[8];
1589     output[9] = aes_state[9];
1590     output[10] = aes_state[10];
1591     output[11] = aes_state[11];
1592     output[12] = aes_state[12];
1593     output[13] = aes_state[13];
1594     output[14] = aes_state[14];
1595     output[15] = aes_state[15];
1596 #else
1597     buf = (UINT *)output;
1598     buf[0] = aes_ptr -> nx_crypto_aes_state[0];
1599     buf[1] = aes_ptr -> nx_crypto_aes_state[1];
1600     buf[2] = aes_ptr -> nx_crypto_aes_state[2];
1601     buf[3] = aes_ptr -> nx_crypto_aes_state[3];
1602 #endif
1603 
1604     return(NX_CRYPTO_SUCCESS);
1605 }
1606 
1607 
1608 /**************************************************************************/
1609 /*                                                                        */
1610 /*  FUNCTION                                               RELEASE        */
1611 /*                                                                        */
1612 /*    _nx_crypto_aes_key_set                              PORTABLE C      */
1613 /*                                                           6.1.10       */
1614 /*  AUTHOR                                                                */
1615 /*                                                                        */
1616 /*    Timothy Stapko, Microsoft Corporation                               */
1617 /*                                                                        */
1618 /*  DESCRIPTION                                                           */
1619 /*                                                                        */
1620 /*    This function configures key for AES encryption and decryption.     */
1621 /*                                                                        */
1622 /*  INPUT                                                                 */
1623 /*                                                                        */
1624 /*    aes_ptr                               Pointer to AES control block  */
1625 /*    key                                   Pointer to key string         */
1626 /*    key_size                              Size of the key, valid values */
1627 /*                                            are:                        */
1628 /*                                        NX_CRYPTO_AES_KEY_SIZE_128_BITS */
1629 /*                                        NX_CRYPTO_AES_KEY_SIZE_192_BITS */
1630 /*                                        NX_CRYPTO_AES_KEY_SIZE_256_BITS */
1631 /*                                                                        */
1632 /*  OUTPUT                                                                */
1633 /*                                                                        */
1634 /*    status                                Completion status             */
1635 /*                                                                        */
1636 /*  CALLS                                                                 */
1637 /*                                                                        */
1638 /*    _nx_crypto_aes_key_expansion          Key expansion for encryption  */
1639 /*    _nx_crypto_aes_key_expansion_inverse  Key expansion for decryption  */
1640 /*                                                                        */
1641 /*  CALLED BY                                                             */
1642 /*                                                                        */
1643 /*    Application Code                                                    */
1644 /*                                                                        */
1645 /*  RELEASE HISTORY                                                       */
1646 /*                                                                        */
1647 /*    DATE              NAME                      DESCRIPTION             */
1648 /*                                                                        */
1649 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
1650 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
1651 /*                                            resulting in version 6.1    */
1652 /*  01-31-2022     Timothy Stapko           Modified comment(s),          */
1653 /*                                            moved inverse key expansion,*/
1654 /*                                            resulting in version 6.1.10 */
1655 /*                                                                        */
1656 /**************************************************************************/
_nx_crypto_aes_key_set(NX_CRYPTO_AES * aes_ptr,UCHAR * key,UINT key_size)1657 NX_CRYPTO_KEEP UINT _nx_crypto_aes_key_set(NX_CRYPTO_AES *aes_ptr, UCHAR *key, UINT key_size)
1658 {
1659 UCHAR *expanded_key;
1660 UINT   i;
1661 
1662     /* Set the AES key size (should be in 32-bit *words*). */
1663     aes_ptr -> nx_crypto_aes_key_size = (USHORT)key_size;
1664 
1665     expanded_key = (UCHAR *)aes_ptr -> nx_crypto_aes_key_schedule;
1666 
1667     /* Copy the key into the beginning of the expanded key buffer. */
1668     for (i = 0; i < key_size * 4; ++i)
1669     {
1670         expanded_key[i]  = key[i];
1671     }
1672 
1673     /* Based on the key size, determine the number of rounds. */
1674     switch (key_size)
1675     {
1676     case NX_CRYPTO_AES_KEY_SIZE_128_BITS:
1677         aes_ptr -> nx_crypto_aes_rounds = 10;
1678         break;
1679     case NX_CRYPTO_AES_KEY_SIZE_192_BITS:
1680         aes_ptr -> nx_crypto_aes_rounds = 12;
1681         break;
1682     /* case NX_CRYPTO_AES_KEY_SIZE_256_BITS: */
1683     default:
1684         aes_ptr -> nx_crypto_aes_rounds = 14;
1685         break;
1686     }
1687 
1688 
1689     _nx_crypto_aes_key_expansion(aes_ptr);
1690 
1691     /* Move key_expansion_inverse into the decrypt logic.
1692        No reason to build the inverse table if the application doesn't do decryption. */
1693     /* Clear the inverse key expansion flag; */
1694     aes_ptr -> nx_crypto_aes_inverse_key_expanded = 0;
1695 
1696     return(NX_CRYPTO_SUCCESS);
1697 }
1698 
1699 /**************************************************************************/
1700 /*                                                                        */
1701 /*  FUNCTION                                               RELEASE        */
1702 /*                                                                        */
1703 /*    _nx_crypto_method_aes_init                          PORTABLE C      */
1704 /*                                                           6.3.0        */
1705 /*  AUTHOR                                                                */
1706 /*                                                                        */
1707 /*    Timothy Stapko, Microsoft Corporation                               */
1708 /*                                                                        */
1709 /*  DESCRIPTION                                                           */
1710 /*                                                                        */
1711 /*    This function initializes the AES crypto module.                    */
1712 /*                                                                        */
1713 /*  INPUT                                                                 */
1714 /*                                                                        */
1715 /*    method                                Crypto Method Object          */
1716 /*    key                                   Key                           */
1717 /*    key_size_in_bits                      Size of the key, in bits      */
1718 /*    handle                                Handle, specified by user     */
1719 /*    crypto_metadata                       Metadata area                 */
1720 /*    crypto_metadata_size                  Size of the metadata area     */
1721 /*                                                                        */
1722 /*  OUTPUT                                                                */
1723 /*                                                                        */
1724 /*    status                                Completion status             */
1725 /*                                                                        */
1726 /*  CALLS                                                                 */
1727 /*                                                                        */
1728 /*    _nx_crypto_aes_key_set                Set the key for AES           */
1729 /*                                                                        */
1730 /*  CALLED BY                                                             */
1731 /*                                                                        */
1732 /*    _nx_crypto_method_aes_operation       Handle AES encrypt or decrypt */
1733 /*                                                                        */
1734 /*  RELEASE HISTORY                                                       */
1735 /*                                                                        */
1736 /*    DATE              NAME                      DESCRIPTION             */
1737 /*                                                                        */
1738 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
1739 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
1740 /*                                            resulting in version 6.1    */
1741 /*  10-31-2023     Yanwu Cai                Modified comment(s),          */
1742 /*                                            resulting in version 6.3.0  */
1743 /*                                                                        */
1744 /**************************************************************************/
_nx_crypto_method_aes_init(struct NX_CRYPTO_METHOD_STRUCT * method,UCHAR * key,NX_CRYPTO_KEY_SIZE key_size_in_bits,VOID ** handle,VOID * crypto_metadata,ULONG crypto_metadata_size)1745 NX_CRYPTO_KEEP UINT  _nx_crypto_method_aes_init(struct NX_CRYPTO_METHOD_STRUCT *method,
1746                                                 UCHAR *key, NX_CRYPTO_KEY_SIZE key_size_in_bits,
1747                                                 VOID **handle,
1748                                                 VOID *crypto_metadata,
1749                                                 ULONG crypto_metadata_size)
1750 {
1751 
1752     NX_CRYPTO_PARAMETER_NOT_USED(handle);
1753 
1754     NX_CRYPTO_STATE_CHECK
1755 
1756 
1757     if ((method == NX_CRYPTO_NULL) || (key == NX_CRYPTO_NULL) || (crypto_metadata == NX_CRYPTO_NULL))
1758     {
1759         return(NX_CRYPTO_PTR_ERROR);
1760     }
1761 
1762     /* Verify the metadata address is 4-byte aligned. */
1763     if((((ULONG)crypto_metadata) & 0x3) != 0)
1764     {
1765         return(NX_CRYPTO_PTR_ERROR);
1766     }
1767 
1768     if(crypto_metadata_size < sizeof(NX_CRYPTO_AES))
1769     {
1770         return(NX_CRYPTO_PTR_ERROR);
1771     }
1772 
1773     /* We only support 128-bit or 256-bit key size for the time-being. */
1774     if ((key_size_in_bits != NX_CRYPTO_AES_128_KEY_LEN_IN_BITS) && (key_size_in_bits != NX_CRYPTO_AES_192_KEY_LEN_IN_BITS) && (key_size_in_bits != NX_CRYPTO_AES_256_KEY_LEN_IN_BITS))
1775     {
1776         return(NX_CRYPTO_UNSUPPORTED_KEY_SIZE);
1777     }
1778 
1779     NX_CRYPTO_MEMSET(&((NX_CRYPTO_AES *)crypto_metadata) -> nx_crypto_aes_mode_context, 0, sizeof(((NX_CRYPTO_AES *)crypto_metadata) -> nx_crypto_aes_mode_context));
1780 
1781     _nx_crypto_aes_key_set((NX_CRYPTO_AES *)crypto_metadata, key, key_size_in_bits >> 5);
1782 
1783     return(NX_CRYPTO_SUCCESS);
1784 }
1785 
1786 
1787 /**************************************************************************/
1788 /*                                                                        */
1789 /*  FUNCTION                                               RELEASE        */
1790 /*                                                                        */
1791 /*    _nx_crypto_method_aes_cleanup                       PORTABLE C      */
1792 /*                                                           6.1          */
1793 /*  AUTHOR                                                                */
1794 /*                                                                        */
1795 /*    Timothy Stapko, Microsoft Corporation                               */
1796 /*                                                                        */
1797 /*  DESCRIPTION                                                           */
1798 /*                                                                        */
1799 /*    This function cleans up the crypto metadata.                        */
1800 /*                                                                        */
1801 /*  INPUT                                                                 */
1802 /*                                                                        */
1803 /*    crypto_metadata                       Crypto metadata               */
1804 /*                                                                        */
1805 /*  OUTPUT                                                                */
1806 /*                                                                        */
1807 /*    status                                Completion status             */
1808 /*                                                                        */
1809 /*  CALLS                                                                 */
1810 /*                                                                        */
1811 /*    NX_CRYPTO_MEMSET                      Set the memory                */
1812 /*                                                                        */
1813 /*  CALLED BY                                                             */
1814 /*                                                                        */
1815 /*    Application Code                                                    */
1816 /*                                                                        */
1817 /*  RELEASE HISTORY                                                       */
1818 /*                                                                        */
1819 /*    DATE              NAME                      DESCRIPTION             */
1820 /*                                                                        */
1821 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
1822 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
1823 /*                                            resulting in version 6.1    */
1824 /*                                                                        */
1825 /**************************************************************************/
_nx_crypto_method_aes_cleanup(VOID * crypto_metadata)1826 NX_CRYPTO_KEEP UINT  _nx_crypto_method_aes_cleanup(VOID *crypto_metadata)
1827 {
1828 
1829     NX_CRYPTO_STATE_CHECK
1830 
1831 #ifdef NX_SECURE_KEY_CLEAR
1832     if (!crypto_metadata)
1833         return (NX_CRYPTO_SUCCESS);
1834 
1835     /* Clean up the crypto metadata.  */
1836     NX_CRYPTO_MEMSET(crypto_metadata, 0, sizeof(NX_CRYPTO_AES));
1837 #else
1838     NX_CRYPTO_PARAMETER_NOT_USED(crypto_metadata);
1839 #endif /* NX_SECURE_KEY_CLEAR  */
1840 
1841     return(NX_CRYPTO_SUCCESS);
1842 }
1843 
1844 
1845 /**************************************************************************/
1846 /*                                                                        */
1847 /*  FUNCTION                                               RELEASE        */
1848 /*                                                                        */
1849 /*    _nx_crypto_method_aes_operation                     PORTABLE C      */
1850 /*                                                           6.3.0        */
1851 /*  AUTHOR                                                                */
1852 /*                                                                        */
1853 /*    Timothy Stapko, Microsoft Corporation                               */
1854 /*                                                                        */
1855 /*  DESCRIPTION                                                           */
1856 /*                                                                        */
1857 /*    This function encrypts and decrypts a message using                 */
1858 /*    the AES algorithm.                                                  */
1859 /*                                                                        */
1860 /*  INPUT                                                                 */
1861 /*                                                                        */
1862 /*    op                                    AES operation                 */
1863 /*    handle                                Crypto handle                 */
1864 /*    method                                Cryption Method Object        */
1865 /*    key                                   Encryption Key                */
1866 /*    key_size_in_bits                      Key size in bits              */
1867 /*    input                                 Input data                    */
1868 /*    input_length_in_byte                  Input data size               */
1869 /*    iv_ptr                                Initial vector                */
1870 /*    output                                Output buffer                 */
1871 /*    output_length_in_byte                 Output buffer size            */
1872 /*    crypto_metadata                       Metadata area                 */
1873 /*    crypto_metadata_size                  Metadata area size            */
1874 /*    packet_ptr                            Pointer to packet             */
1875 /*    nx_crypto_hw_process_callback         Callback function pointer     */
1876 /*                                                                        */
1877 /*  OUTPUT                                                                */
1878 /*                                                                        */
1879 /*    status                                Completion status             */
1880 /*                                                                        */
1881 /*  CALLS                                                                 */
1882 /*                                                                        */
1883 /*    _nx_crypto_method_aes_cbc_operation   Handle AES CBC operation      */
1884 /*    _nx_crypto_method_aes_ccm_operation   Handle AES CCM operation      */
1885 /*    _nx_crypto_method_aes_gcm_operation   Handle AES GCM operation      */
1886 /*    _nx_crypto_method_aes_ctr_operation   Handle AES CTR operation      */
1887 /*    _nx_crypto_method_aes_xcbc_operation  Handle AES XCBC operation     */
1888 /*                                                                        */
1889 /*  CALLED BY                                                             */
1890 /*                                                                        */
1891 /*    Application Code                                                    */
1892 /*                                                                        */
1893 /*  RELEASE HISTORY                                                       */
1894 /*                                                                        */
1895 /*    DATE              NAME                      DESCRIPTION             */
1896 /*                                                                        */
1897 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
1898 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
1899 /*                                            resulting in version 6.1    */
1900 /*  10-31-2023     Yanwu Cai                Modified comment(s),          */
1901 /*                                            resulting in version 6.3.0  */
1902 /*                                                                        */
1903 /**************************************************************************/
_nx_crypto_method_aes_operation(UINT op,VOID * handle,struct NX_CRYPTO_METHOD_STRUCT * method,UCHAR * key,NX_CRYPTO_KEY_SIZE key_size_in_bits,UCHAR * input,ULONG input_length_in_byte,UCHAR * iv_ptr,UCHAR * output,ULONG output_length_in_byte,VOID * crypto_metadata,ULONG crypto_metadata_size,VOID * packet_ptr,VOID (* nx_crypto_hw_process_callback)(VOID * packet_ptr,UINT status))1904 NX_CRYPTO_KEEP UINT  _nx_crypto_method_aes_operation(UINT op,      /* Encrypt, Decrypt, Authenticate */
1905                                                      VOID *handle, /* Crypto handler */
1906                                                      struct NX_CRYPTO_METHOD_STRUCT *method,
1907                                                      UCHAR *key,
1908                                                      NX_CRYPTO_KEY_SIZE key_size_in_bits,
1909                                                      UCHAR *input,
1910                                                      ULONG input_length_in_byte,
1911                                                      UCHAR *iv_ptr,
1912                                                      UCHAR *output,
1913                                                      ULONG output_length_in_byte,
1914                                                      VOID *crypto_metadata,
1915                                                      ULONG crypto_metadata_size,
1916                                                      VOID *packet_ptr,
1917                                                      VOID (*nx_crypto_hw_process_callback)(VOID *packet_ptr, UINT status))
1918 {
1919 UINT    status;
1920 
1921     NX_CRYPTO_STATE_CHECK
1922 
1923     /* Verify the metadata address is 4-byte aligned. */
1924     if((method == NX_CRYPTO_NULL) || (crypto_metadata == NX_CRYPTO_NULL) || ((((ULONG)crypto_metadata) & 0x3) != 0))
1925     {
1926         return(NX_CRYPTO_PTR_ERROR);
1927     }
1928 
1929     if(crypto_metadata_size < sizeof(NX_CRYPTO_AES))
1930     {
1931         return(NX_CRYPTO_PTR_ERROR);
1932     }
1933 
1934     /* Check if the algorithm is cbc or ctr. */
1935     if (method -> nx_crypto_algorithm == NX_CRYPTO_ENCRYPTION_AES_CBC)
1936     {
1937 
1938         /* AES CBC */
1939         status = _nx_crypto_method_aes_cbc_operation(op, handle, method, key, key_size_in_bits,
1940                                                      input, input_length_in_byte, iv_ptr,
1941                                                      output, output_length_in_byte,
1942                                                      crypto_metadata, crypto_metadata_size,
1943                                                      packet_ptr, nx_crypto_hw_process_callback);
1944     }
1945     else if ((method -> nx_crypto_algorithm >= NX_CRYPTO_ENCRYPTION_AES_CCM_8) &&
1946              (method -> nx_crypto_algorithm <= NX_CRYPTO_ENCRYPTION_AES_CCM))
1947     {
1948 
1949         /* AES CCM */
1950         status = _nx_crypto_method_aes_ccm_operation(op, handle, method, key, key_size_in_bits,
1951                                                      input, input_length_in_byte, iv_ptr,
1952                                                      output, output_length_in_byte,
1953                                                      crypto_metadata, crypto_metadata_size,
1954                                                      packet_ptr, nx_crypto_hw_process_callback);
1955 
1956     }
1957     else if ((method -> nx_crypto_algorithm >= NX_CRYPTO_ENCRYPTION_AES_GCM_8) &&
1958              (method -> nx_crypto_algorithm <= NX_CRYPTO_ENCRYPTION_AES_GCM_16))
1959     {
1960 
1961         /* AES GCM */
1962         status = _nx_crypto_method_aes_gcm_operation(op, handle, method, key, key_size_in_bits,
1963                                                      input, input_length_in_byte, iv_ptr,
1964                                                      output, output_length_in_byte,
1965                                                      crypto_metadata, crypto_metadata_size,
1966                                                      packet_ptr, nx_crypto_hw_process_callback);
1967 
1968     }
1969     else if (method -> nx_crypto_algorithm == NX_CRYPTO_ENCRYPTION_AES_CTR)
1970     {
1971 
1972         /* AES_CTR */
1973         status = _nx_crypto_method_aes_ctr_operation(op, handle, method, key, key_size_in_bits,
1974                                                      input, input_length_in_byte, iv_ptr,
1975                                                      output, output_length_in_byte,
1976                                                      crypto_metadata, crypto_metadata_size,
1977                                                      packet_ptr, nx_crypto_hw_process_callback);
1978     }
1979     else if (method -> nx_crypto_algorithm == NX_CRYPTO_AUTHENTICATION_AES_XCBC_MAC_96)
1980     {
1981         status = _nx_crypto_method_aes_xcbc_operation(op, handle, method, key, key_size_in_bits,
1982                                                       input, input_length_in_byte, iv_ptr,
1983                                                       output, output_length_in_byte,
1984                                                       crypto_metadata, crypto_metadata_size,
1985                                                       packet_ptr, nx_crypto_hw_process_callback);
1986     }
1987     else
1988     {
1989         status = NX_CRYPTO_INVALID_ALGORITHM;
1990     }
1991 
1992     return status;
1993 }
1994 
1995 /**************************************************************************/
1996 /*                                                                        */
1997 /*  FUNCTION                                               RELEASE        */
1998 /*                                                                        */
1999 /*    _nx_crypto_method_aes_cbc_operation                 PORTABLE C      */
2000 /*                                                           6.3.0        */
2001 /*  AUTHOR                                                                */
2002 /*                                                                        */
2003 /*    Timothy Stapko, Microsoft Corporation                               */
2004 /*                                                                        */
2005 /*  DESCRIPTION                                                           */
2006 /*                                                                        */
2007 /*    This function encrypts and decrypts a message using                 */
2008 /*    the AES CBC algorithm.                                              */
2009 /*                                                                        */
2010 /*  INPUT                                                                 */
2011 /*                                                                        */
2012 /*    op                                    AES operation                 */
2013 /*    handle                                Crypto handle                 */
2014 /*    method                                Cryption Method Object        */
2015 /*    key                                   Encryption Key                */
2016 /*    key_size_in_bits                      Key size in bits              */
2017 /*    input                                 Input data                    */
2018 /*    input_length_in_byte                  Input data size               */
2019 /*    iv_ptr                                Initial vector                */
2020 /*    output                                Output buffer                 */
2021 /*    output_length_in_byte                 Output buffer size            */
2022 /*    crypto_metadata                       Metadata area                 */
2023 /*    crypto_metadata_size                  Metadata area size            */
2024 /*    packet_ptr                            Pointer to packet             */
2025 /*    nx_crypto_hw_process_callback         Callback function pointer     */
2026 /*                                                                        */
2027 /*  OUTPUT                                                                */
2028 /*                                                                        */
2029 /*    status                                Completion status             */
2030 /*                                                                        */
2031 /*  CALLS                                                                 */
2032 /*                                                                        */
2033 /*    _nx_crypto_cbc_encrypt                Perform CBC mode encryption   */
2034 /*    _nx_crypto_cbc_decrypt                Perform CBC mode decryption   */
2035 /*                                                                        */
2036 /*  CALLED BY                                                             */
2037 /*                                                                        */
2038 /*    Application Code                                                    */
2039 /*                                                                        */
2040 /*  RELEASE HISTORY                                                       */
2041 /*                                                                        */
2042 /*    DATE              NAME                      DESCRIPTION             */
2043 /*                                                                        */
2044 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
2045 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
2046 /*                                            resulting in version 6.1    */
2047 /*  10-31-2023     Yanwu Cai                Modified comment(s),          */
2048 /*                                            resulting in version 6.3.0  */
2049 /*                                                                        */
2050 /**************************************************************************/
_nx_crypto_method_aes_cbc_operation(UINT op,VOID * handle,struct NX_CRYPTO_METHOD_STRUCT * method,UCHAR * key,NX_CRYPTO_KEY_SIZE key_size_in_bits,UCHAR * input,ULONG input_length_in_byte,UCHAR * iv_ptr,UCHAR * output,ULONG output_length_in_byte,VOID * crypto_metadata,ULONG crypto_metadata_size,VOID * packet_ptr,VOID (* nx_crypto_hw_process_callback)(VOID * packet_ptr,UINT status))2051 NX_CRYPTO_KEEP UINT  _nx_crypto_method_aes_cbc_operation(UINT op,      /* Encrypt, Decrypt, Authenticate */
2052                                                          VOID *handle, /* Crypto handler */
2053                                                          struct NX_CRYPTO_METHOD_STRUCT *method,
2054                                                          UCHAR *key,
2055                                                          NX_CRYPTO_KEY_SIZE key_size_in_bits,
2056                                                          UCHAR *input,
2057                                                          ULONG input_length_in_byte,
2058                                                          UCHAR *iv_ptr,
2059                                                          UCHAR *output,
2060                                                          ULONG output_length_in_byte,
2061                                                          VOID *crypto_metadata,
2062                                                          ULONG crypto_metadata_size,
2063                                                          VOID *packet_ptr,
2064                                                          VOID (*nx_crypto_hw_process_callback)(VOID *packet_ptr, UINT status))
2065 {
2066 
2067 NX_CRYPTO_AES *ctx;
2068 UINT    status;
2069 
2070     NX_CRYPTO_PARAMETER_NOT_USED(handle);
2071     NX_CRYPTO_PARAMETER_NOT_USED(key);
2072     NX_CRYPTO_PARAMETER_NOT_USED(key_size_in_bits);
2073     NX_CRYPTO_PARAMETER_NOT_USED(output_length_in_byte);
2074     NX_CRYPTO_PARAMETER_NOT_USED(packet_ptr);
2075     NX_CRYPTO_PARAMETER_NOT_USED(nx_crypto_hw_process_callback);
2076 
2077     NX_CRYPTO_STATE_CHECK
2078 
2079     /* Verify the metadata address is 4-byte aligned. */
2080     if((method == NX_CRYPTO_NULL) || (crypto_metadata == NX_CRYPTO_NULL) || ((((ULONG)crypto_metadata) & 0x3) != 0))
2081     {
2082         return(NX_CRYPTO_PTR_ERROR);
2083     }
2084 
2085     if(crypto_metadata_size < sizeof(NX_CRYPTO_AES))
2086     {
2087         return(NX_CRYPTO_PTR_ERROR);
2088     }
2089 
2090     ctx = (NX_CRYPTO_AES *)crypto_metadata;
2091 
2092     switch (op)
2093     {
2094         case NX_CRYPTO_DECRYPT:
2095         {
2096             status = _nx_crypto_cbc_decrypt_init(&(ctx -> nx_crypto_aes_mode_context.cbc),
2097                                                  iv_ptr, method -> nx_crypto_IV_size_in_bits >> 3);
2098             if (status)
2099             {
2100                 break;
2101             }
2102 
2103             status = _nx_crypto_cbc_decrypt(ctx, &(ctx -> nx_crypto_aes_mode_context.cbc),
2104                                             (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_decrypt,
2105                                             input, output, input_length_in_byte,
2106                                             NX_CRYPTO_AES_BLOCK_SIZE);
2107         } break;
2108 
2109         case NX_CRYPTO_ENCRYPT:
2110         {
2111             status = _nx_crypto_cbc_encrypt_init(&(ctx -> nx_crypto_aes_mode_context.cbc),
2112                                                  iv_ptr, method -> nx_crypto_IV_size_in_bits >> 3);
2113             if (status)
2114             {
2115                 break;
2116             }
2117 
2118             status = _nx_crypto_cbc_encrypt(ctx, &(ctx -> nx_crypto_aes_mode_context.cbc),
2119                                             (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2120                                             input, output, input_length_in_byte,
2121                                             NX_CRYPTO_AES_BLOCK_SIZE);
2122         } break;
2123 
2124         case NX_CRYPTO_DECRYPT_INITIALIZE:
2125         {
2126             status = _nx_crypto_cbc_decrypt_init(&(ctx -> nx_crypto_aes_mode_context.cbc),
2127                                                  iv_ptr, method -> nx_crypto_IV_size_in_bits >> 3);
2128         } break;
2129 
2130         case NX_CRYPTO_ENCRYPT_INITIALIZE:
2131         {
2132             status = _nx_crypto_cbc_encrypt_init(&(ctx -> nx_crypto_aes_mode_context.cbc),
2133                                                  iv_ptr, method -> nx_crypto_IV_size_in_bits >> 3);
2134         } break;
2135 
2136         case NX_CRYPTO_DECRYPT_UPDATE:
2137         {
2138             status = _nx_crypto_cbc_decrypt(ctx, &(ctx -> nx_crypto_aes_mode_context.cbc),
2139                                             (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_decrypt,
2140                                             input, output, input_length_in_byte,
2141                                             NX_CRYPTO_AES_BLOCK_SIZE);
2142         } break;
2143 
2144         case NX_CRYPTO_ENCRYPT_UPDATE:
2145         {
2146             status = _nx_crypto_cbc_encrypt(ctx, &(ctx -> nx_crypto_aes_mode_context.cbc),
2147                                             (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2148                                             input, output, input_length_in_byte,
2149                                             NX_CRYPTO_AES_BLOCK_SIZE);
2150         } break;
2151 
2152         case NX_CRYPTO_ENCRYPT_CALCULATE:
2153         /* fallthrough */
2154         case NX_CRYPTO_DECRYPT_CALCULATE:
2155         {
2156 
2157             /* Nothing to do. */
2158             status = NX_CRYPTO_SUCCESS;
2159         } break;
2160 
2161         default:
2162         {
2163             status = NX_CRYPTO_INVALID_ALGORITHM;
2164         } break;
2165     }
2166 
2167     return(status);
2168 }
2169 
2170 /**************************************************************************/
2171 /*                                                                        */
2172 /*  FUNCTION                                               RELEASE        */
2173 /*                                                                        */
2174 /*    _nx_crypto_method_aes_ccm_operation                 PORTABLE C      */
2175 /*                                                           6.3.0        */
2176 /*  AUTHOR                                                                */
2177 /*                                                                        */
2178 /*    Timothy Stapko, Microsoft Corporation                               */
2179 /*                                                                        */
2180 /*  DESCRIPTION                                                           */
2181 /*                                                                        */
2182 /*    This function encrypts and decrypts a message using                 */
2183 /*    the AES CCM algorithm.                                              */
2184 /*                                                                        */
2185 /*  INPUT                                                                 */
2186 /*                                                                        */
2187 /*    op                                    AES operation                 */
2188 /*    handle                                Crypto handle                 */
2189 /*    method                                Cryption Method Object        */
2190 /*    key                                   Encryption Key                */
2191 /*    key_size_in_bits                      Key size in bits              */
2192 /*    input                                 Input data                    */
2193 /*    input_length_in_byte                  Input data size               */
2194 /*    iv_ptr                                Initial vector                */
2195 /*    output                                Output buffer                 */
2196 /*    output_length_in_byte                 Output buffer size            */
2197 /*    crypto_metadata                       Metadata area                 */
2198 /*    crypto_metadata_size                  Metadata area size            */
2199 /*    packet_ptr                            Pointer to packet             */
2200 /*    nx_crypto_hw_process_callback         Callback function pointer     */
2201 /*                                                                        */
2202 /*  OUTPUT                                                                */
2203 /*                                                                        */
2204 /*    status                                Completion status             */
2205 /*                                                                        */
2206 /*  CALLS                                                                 */
2207 /*                                                                        */
2208 /*    _nx_crypto_cbc_encrypt                Perform CBC mode encryption   */
2209 /*    _nx_crypto_cbc_decrypt                Perform CBC mode decryption   */
2210 /*                                                                        */
2211 /*  CALLED BY                                                             */
2212 /*                                                                        */
2213 /*    _nx_crypto_method_aes_operation       Handle AES encrypt or decrypt */
2214 /*    Application Code                                                    */
2215 /*                                                                        */
2216 /*  RELEASE HISTORY                                                       */
2217 /*                                                                        */
2218 /*    DATE              NAME                      DESCRIPTION             */
2219 /*                                                                        */
2220 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
2221 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
2222 /*                                            resulting in version 6.1    */
2223 /*  03-08-2023     Tiejun Zhou              Modified comment(s), and      */
2224 /*                                            fixed compiler warnings,    */
2225 /*                                            resulting in version 6.2.1  */
2226 /*  10-31-2023     Yanwu Cai                Modified comment(s),          */
2227 /*                                            resulting in version 6.3.0  */
2228 /*                                                                        */
2229 /**************************************************************************/
_nx_crypto_method_aes_ccm_operation(UINT op,VOID * handle,struct NX_CRYPTO_METHOD_STRUCT * method,UCHAR * key,NX_CRYPTO_KEY_SIZE key_size_in_bits,UCHAR * input,ULONG input_length_in_byte,UCHAR * iv_ptr,UCHAR * output,ULONG output_length_in_byte,VOID * crypto_metadata,ULONG crypto_metadata_size,VOID * packet_ptr,VOID (* nx_crypto_hw_process_callback)(VOID * packet_ptr,UINT status))2230 NX_CRYPTO_KEEP UINT  _nx_crypto_method_aes_ccm_operation(UINT op,      /* Encrypt, Decrypt, Authenticate */
2231                                                          VOID *handle, /* Crypto handler */
2232                                                          struct NX_CRYPTO_METHOD_STRUCT *method,
2233                                                          UCHAR *key,
2234                                                          NX_CRYPTO_KEY_SIZE key_size_in_bits,
2235                                                          UCHAR *input,
2236                                                          ULONG input_length_in_byte,
2237                                                          UCHAR *iv_ptr,
2238                                                          UCHAR *output,
2239                                                          ULONG output_length_in_byte,
2240                                                          VOID *crypto_metadata,
2241                                                          ULONG crypto_metadata_size,
2242                                                          VOID *packet_ptr,
2243                                                          VOID (*nx_crypto_hw_process_callback)(VOID *packet_ptr, UINT status))
2244 {
2245 
2246 NX_CRYPTO_AES *ctx;
2247 UINT    status;
2248 
2249     NX_CRYPTO_PARAMETER_NOT_USED(handle);
2250     NX_CRYPTO_PARAMETER_NOT_USED(key);
2251     NX_CRYPTO_PARAMETER_NOT_USED(key_size_in_bits);
2252     NX_CRYPTO_PARAMETER_NOT_USED(output_length_in_byte);
2253     NX_CRYPTO_PARAMETER_NOT_USED(packet_ptr);
2254     NX_CRYPTO_PARAMETER_NOT_USED(nx_crypto_hw_process_callback);
2255 
2256     NX_CRYPTO_STATE_CHECK
2257 
2258     /* Verify the metadata address is 4-byte aligned. */
2259     if((method == NX_CRYPTO_NULL) || (crypto_metadata == NX_CRYPTO_NULL) || ((((ULONG)crypto_metadata) & 0x3) != 0))
2260     {
2261         return(NX_CRYPTO_PTR_ERROR);
2262     }
2263 
2264     if(crypto_metadata_size < sizeof(NX_CRYPTO_AES))
2265     {
2266         return(NX_CRYPTO_PTR_ERROR);
2267     }
2268 
2269     ctx = (NX_CRYPTO_AES *)crypto_metadata;
2270 
2271     if ((method -> nx_crypto_algorithm < NX_CRYPTO_ENCRYPTION_AES_CCM_8) ||
2272         (method -> nx_crypto_algorithm > NX_CRYPTO_ENCRYPTION_AES_CCM))
2273     {
2274         return(NX_CRYPTO_INVALID_ALGORITHM);
2275     }
2276 
2277     /* IV : Nonce length(1 byte) + Nonce
2278        nx_crypto_ICV_size_in_bits: authentication tag length in bits */
2279     switch (op)
2280     {
2281         case NX_CRYPTO_DECRYPT:
2282         {
2283             if (iv_ptr == NX_CRYPTO_NULL ||
2284                 (ctx -> nx_crypto_aes_mode_context.ccm.nx_crypto_ccm_additional_data_len > 0 &&
2285                  ctx -> nx_crypto_aes_mode_context.ccm.nx_crypto_ccm_additional_data == NX_CRYPTO_NULL))
2286             {
2287                 status = NX_CRYPTO_PTR_ERROR;
2288                 break;
2289             }
2290 
2291             if (input_length_in_byte < (ULONG)(method -> nx_crypto_ICV_size_in_bits >> 3) ||
2292                 output_length_in_byte < input_length_in_byte - (method -> nx_crypto_ICV_size_in_bits >> 3))
2293             {
2294                 status = NX_CRYPTO_INVALID_BUFFER_SIZE;
2295                 break;
2296             }
2297 
2298             status = _nx_crypto_ccm_decrypt_init(ctx, &(ctx -> nx_crypto_aes_mode_context.ccm),
2299                                                  (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2300                                                  ctx -> nx_crypto_aes_mode_context.ccm.nx_crypto_ccm_additional_data,
2301                                                  ctx -> nx_crypto_aes_mode_context.ccm.nx_crypto_ccm_additional_data_len,
2302                                                  input_length_in_byte - (method -> nx_crypto_ICV_size_in_bits >> 3), iv_ptr,
2303                                                  (UCHAR)(method -> nx_crypto_ICV_size_in_bits >> 3),
2304                                                  NX_CRYPTO_AES_BLOCK_SIZE);
2305 
2306             if (status)
2307             {
2308                 break;
2309             }
2310 
2311             status = _nx_crypto_ccm_decrypt_update(NX_CRYPTO_DECRYPT_UPDATE,
2312                                                    ctx, &(ctx -> nx_crypto_aes_mode_context.ccm),
2313                                                    (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2314                                                    input, output, input_length_in_byte - (method -> nx_crypto_ICV_size_in_bits >> 3),
2315                                                    NX_CRYPTO_AES_BLOCK_SIZE);
2316             if (status)
2317             {
2318                 break;
2319             }
2320 
2321             status = _nx_crypto_ccm_decrypt_calculate(ctx, &(ctx -> nx_crypto_aes_mode_context.ccm),
2322                                                       (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2323                                                       input + input_length_in_byte - (method -> nx_crypto_ICV_size_in_bits >> 3),
2324                                                       NX_CRYPTO_AES_BLOCK_SIZE);
2325             if (status)
2326             {
2327                 break;
2328             }
2329         } break;
2330 
2331         case NX_CRYPTO_ENCRYPT:
2332         {
2333             if (iv_ptr == NX_CRYPTO_NULL ||
2334                 (ctx -> nx_crypto_aes_mode_context.ccm.nx_crypto_ccm_additional_data_len > 0 &&
2335                  ctx -> nx_crypto_aes_mode_context.ccm.nx_crypto_ccm_additional_data == NX_CRYPTO_NULL))
2336             {
2337                 status = NX_CRYPTO_PTR_ERROR;
2338                 break;
2339             }
2340 
2341             if (output_length_in_byte < input_length_in_byte + (method -> nx_crypto_ICV_size_in_bits >> 3))
2342             {
2343                 status = NX_CRYPTO_INVALID_BUFFER_SIZE;
2344                 break;
2345             }
2346 
2347             status = _nx_crypto_ccm_encrypt_init(ctx, &(ctx -> nx_crypto_aes_mode_context.ccm),
2348                                                  (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2349                                                  ctx -> nx_crypto_aes_mode_context.ccm.nx_crypto_ccm_additional_data,
2350                                                  ctx -> nx_crypto_aes_mode_context.ccm.nx_crypto_ccm_additional_data_len,
2351                                                  input_length_in_byte, iv_ptr,
2352                                                  (UCHAR)(method -> nx_crypto_ICV_size_in_bits >> 3),
2353                                                  NX_CRYPTO_AES_BLOCK_SIZE);
2354 
2355             if (status)
2356             {
2357                 break;
2358             }
2359 
2360             status = _nx_crypto_ccm_encrypt_update(NX_CRYPTO_ENCRYPT_UPDATE,
2361                                                    ctx, &(ctx -> nx_crypto_aes_mode_context.ccm),
2362                                                    (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2363                                                    input, output, input_length_in_byte,
2364                                                    NX_CRYPTO_AES_BLOCK_SIZE);
2365             if (status)
2366             {
2367                 break;
2368             }
2369 
2370             status = _nx_crypto_ccm_encrypt_calculate(ctx, &(ctx -> nx_crypto_aes_mode_context.ccm),
2371                                                       (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2372                                                       output + input_length_in_byte,
2373                                                       NX_CRYPTO_AES_BLOCK_SIZE);
2374             if (status)
2375             {
2376                 break;
2377             }
2378         } break;
2379 
2380         case NX_CRYPTO_SET_ADDITIONAL_DATA:
2381         {
2382 
2383             /* Set additonal data pointer.  */
2384             ctx -> nx_crypto_aes_mode_context.ccm.nx_crypto_ccm_additional_data = (VOID *)input;
2385 
2386             /* Set additional data length.  */
2387             ctx -> nx_crypto_aes_mode_context.ccm.nx_crypto_ccm_additional_data_len = input_length_in_byte;
2388 
2389             status = NX_CRYPTO_SUCCESS;
2390         } break;
2391 
2392         case NX_CRYPTO_DECRYPT_INITIALIZE:
2393         {
2394             if (iv_ptr == NX_CRYPTO_NULL)
2395             {
2396                 status = NX_CRYPTO_PTR_ERROR;
2397                 break;
2398             }
2399 
2400             status = _nx_crypto_ccm_decrypt_init(ctx, &(ctx -> nx_crypto_aes_mode_context.ccm),
2401                                                  (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2402                                                  input, /* pointers to AAD */
2403                                                  input_length_in_byte, /* length of AAD */
2404                                                  output_length_in_byte, /* total length of message */
2405                                                  iv_ptr,
2406                                                  (UCHAR)(method -> nx_crypto_ICV_size_in_bits >> 3),
2407                                                  NX_CRYPTO_AES_BLOCK_SIZE);
2408         } break;
2409 
2410         case NX_CRYPTO_DECRYPT_UPDATE:
2411         {
2412             status = _nx_crypto_ccm_decrypt_update(NX_CRYPTO_DECRYPT_UPDATE,
2413                                                    ctx, &(ctx -> nx_crypto_aes_mode_context.ccm),
2414                                                    (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2415                                                    input, output, input_length_in_byte,
2416                                                    NX_CRYPTO_AES_BLOCK_SIZE);
2417 
2418         } break;
2419 
2420         case NX_CRYPTO_DECRYPT_CALCULATE:
2421         {
2422             status = _nx_crypto_ccm_decrypt_calculate(ctx, &(ctx -> nx_crypto_aes_mode_context.ccm),
2423                                                       (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2424                                                       input, NX_CRYPTO_AES_BLOCK_SIZE);
2425         } break;
2426 
2427         case NX_CRYPTO_ENCRYPT_INITIALIZE:
2428         {
2429             if (iv_ptr == NX_CRYPTO_NULL)
2430             {
2431                 status = NX_CRYPTO_PTR_ERROR;
2432                 break;
2433             }
2434 
2435             status = _nx_crypto_ccm_encrypt_init(ctx, &(ctx -> nx_crypto_aes_mode_context.ccm),
2436                                                  (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2437                                                  input, /* pointers to AAD */
2438                                                  input_length_in_byte, /* length of AAD */
2439                                                  output_length_in_byte, /* total length of message */
2440                                                  iv_ptr,
2441                                                  (UCHAR)(method -> nx_crypto_ICV_size_in_bits >> 3),
2442                                                  NX_CRYPTO_AES_BLOCK_SIZE);
2443         } break;
2444 
2445         case NX_CRYPTO_ENCRYPT_UPDATE:
2446         {
2447 
2448             status = _nx_crypto_ccm_encrypt_update(NX_CRYPTO_ENCRYPT_UPDATE,
2449                                                    ctx, &(ctx -> nx_crypto_aes_mode_context.ccm),
2450                                                    (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2451                                                    input, output, input_length_in_byte,
2452                                                    NX_CRYPTO_AES_BLOCK_SIZE);
2453         } break;
2454 
2455         case NX_CRYPTO_ENCRYPT_CALCULATE:
2456         {
2457 
2458             status = _nx_crypto_ccm_encrypt_calculate(ctx, &(ctx -> nx_crypto_aes_mode_context.ccm),
2459                                                       (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2460                                                       output, NX_CRYPTO_AES_BLOCK_SIZE);
2461         } break;
2462 
2463         default:
2464         {
2465             status = NX_CRYPTO_INVALID_ALGORITHM;
2466         } break;
2467     }
2468 
2469     return(status);
2470 }
2471 
2472 /**************************************************************************/
2473 /*                                                                        */
2474 /*  FUNCTION                                               RELEASE        */
2475 /*                                                                        */
2476 /*    _nx_crypto_method_aes_gcm_operation                 PORTABLE C      */
2477 /*                                                           6.3.0        */
2478 /*  AUTHOR                                                                */
2479 /*                                                                        */
2480 /*    Timothy Stapko, Microsoft Corporation                               */
2481 /*                                                                        */
2482 /*  DESCRIPTION                                                           */
2483 /*                                                                        */
2484 /*    This function encrypts and decrypts a message using                 */
2485 /*    the AES GCM algorithm.                                              */
2486 /*                                                                        */
2487 /*  INPUT                                                                 */
2488 /*                                                                        */
2489 /*    op                                    AES operation                 */
2490 /*    handle                                Crypto handle                 */
2491 /*    method                                Cryption Method Object        */
2492 /*    key                                   Encryption Key                */
2493 /*    key_size_in_bits                      Key size in bits              */
2494 /*    input                                 Input data                    */
2495 /*    input_length_in_byte                  Input data size               */
2496 /*    iv_ptr                                Initial vector                */
2497 /*    output                                Output buffer                 */
2498 /*    output_length_in_byte                 Output buffer size            */
2499 /*    crypto_metadata                       Metadata area                 */
2500 /*    crypto_metadata_size                  Metadata area size            */
2501 /*    packet_ptr                            Pointer to packet             */
2502 /*    nx_crypto_hw_process_callback         Callback function pointer     */
2503 /*                                                                        */
2504 /*  OUTPUT                                                                */
2505 /*                                                                        */
2506 /*    status                                Completion status             */
2507 /*                                                                        */
2508 /*  CALLS                                                                 */
2509 /*                                                                        */
2510 /*    _nx_crypto_gcm_operation              Perform GCM encryption or     */
2511 /*                                            decryption                  */
2512 /*                                                                        */
2513 /*  CALLED BY                                                             */
2514 /*                                                                        */
2515 /*    _nx_crypto_method_aes_operation       Handle AES encrypt or decrypt */
2516 /*    Application Code                                                    */
2517 /*                                                                        */
2518 /*  RELEASE HISTORY                                                       */
2519 /*                                                                        */
2520 /*    DATE              NAME                      DESCRIPTION             */
2521 /*                                                                        */
2522 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
2523 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
2524 /*                                            resulting in version 6.1    */
2525 /*  10-31-2023     Yanwu Cai                Modified comment(s),          */
2526 /*                                            resulting in version 6.3.0  */
2527 /*                                                                        */
2528 /**************************************************************************/
_nx_crypto_method_aes_gcm_operation(UINT op,VOID * handle,struct NX_CRYPTO_METHOD_STRUCT * method,UCHAR * key,NX_CRYPTO_KEY_SIZE key_size_in_bits,UCHAR * input,ULONG input_length_in_byte,UCHAR * iv_ptr,UCHAR * output,ULONG output_length_in_byte,VOID * crypto_metadata,ULONG crypto_metadata_size,VOID * packet_ptr,VOID (* nx_crypto_hw_process_callback)(VOID * packet_ptr,UINT status))2529 NX_CRYPTO_KEEP UINT  _nx_crypto_method_aes_gcm_operation(UINT op,      /* Encrypt, Decrypt, Authenticate */
2530                                                          VOID *handle, /* Crypto handler */
2531                                                          struct NX_CRYPTO_METHOD_STRUCT *method,
2532                                                          UCHAR *key,
2533                                                          NX_CRYPTO_KEY_SIZE key_size_in_bits,
2534                                                          UCHAR *input,
2535                                                          ULONG input_length_in_byte,
2536                                                          UCHAR *iv_ptr,
2537                                                          UCHAR *output,
2538                                                          ULONG output_length_in_byte,
2539                                                          VOID *crypto_metadata,
2540                                                          ULONG crypto_metadata_size,
2541                                                          VOID *packet_ptr,
2542                                                          VOID (*nx_crypto_hw_process_callback)(VOID *packet_ptr, UINT status))
2543 {
2544 
2545 NX_CRYPTO_AES *ctx;
2546 UINT icv_len;
2547 UINT message_len;
2548 UINT    status;
2549 
2550     NX_CRYPTO_PARAMETER_NOT_USED(handle);
2551     NX_CRYPTO_PARAMETER_NOT_USED(key);
2552     NX_CRYPTO_PARAMETER_NOT_USED(key_size_in_bits);
2553     NX_CRYPTO_PARAMETER_NOT_USED(output_length_in_byte);
2554     NX_CRYPTO_PARAMETER_NOT_USED(packet_ptr);
2555     NX_CRYPTO_PARAMETER_NOT_USED(nx_crypto_hw_process_callback);
2556 
2557     NX_CRYPTO_STATE_CHECK
2558 
2559     /* Verify the metadata address is 4-byte aligned. */
2560     if((method == NX_CRYPTO_NULL) || (crypto_metadata == NX_CRYPTO_NULL) || ((((ULONG)crypto_metadata) & 0x3) != 0))
2561     {
2562         return(NX_CRYPTO_PTR_ERROR);
2563     }
2564 
2565     if(crypto_metadata_size < sizeof(NX_CRYPTO_AES))
2566     {
2567         return(NX_CRYPTO_PTR_ERROR);
2568     }
2569 
2570     ctx = (NX_CRYPTO_AES *)crypto_metadata;
2571 
2572     if ((method -> nx_crypto_algorithm < NX_CRYPTO_ENCRYPTION_AES_GCM_8) ||
2573         (method -> nx_crypto_algorithm > NX_CRYPTO_ENCRYPTION_AES_GCM_16))
2574     {
2575         return(NX_CRYPTO_INVALID_ALGORITHM);
2576     }
2577 
2578     /* IV : Nonce length(1 byte) + Nonce
2579        nx_crypto_ICV_size_in_bits: authentication tag length in bits */
2580     switch (op)
2581     {
2582         case NX_CRYPTO_DECRYPT:
2583         {
2584             if (iv_ptr == NX_CRYPTO_NULL ||
2585                 (ctx -> nx_crypto_aes_mode_context.gcm.nx_crypto_gcm_additional_data_len > 0 &&
2586                  ctx -> nx_crypto_aes_mode_context.gcm.nx_crypto_gcm_additional_data == NX_CRYPTO_NULL))
2587             {
2588                 status = NX_CRYPTO_PTR_ERROR;
2589                 break;
2590             }
2591 
2592             icv_len = (method -> nx_crypto_ICV_size_in_bits >> 3);
2593 
2594             if (input_length_in_byte < icv_len || output_length_in_byte < input_length_in_byte - icv_len)
2595             {
2596                 status = NX_CRYPTO_INVALID_BUFFER_SIZE;
2597                 break;
2598             }
2599 
2600             message_len = input_length_in_byte - icv_len;
2601             status = _nx_crypto_gcm_decrypt_init(ctx, &(ctx -> nx_crypto_aes_mode_context.gcm),
2602                                                  (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2603                                                  ctx -> nx_crypto_aes_mode_context.gcm.nx_crypto_gcm_additional_data,
2604                                                  ctx -> nx_crypto_aes_mode_context.gcm.nx_crypto_gcm_additional_data_len,
2605                                                  iv_ptr, NX_CRYPTO_AES_BLOCK_SIZE);
2606 
2607             if (status)
2608             {
2609                 break;
2610             }
2611 
2612             status = _nx_crypto_gcm_decrypt_update(ctx, &(ctx -> nx_crypto_aes_mode_context.gcm),
2613                                                    (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2614                                                    input, output, message_len,
2615                                                    NX_CRYPTO_AES_BLOCK_SIZE);
2616 
2617             if (status)
2618             {
2619                 break;
2620             }
2621 
2622             status = _nx_crypto_gcm_decrypt_calculate(ctx, &(ctx -> nx_crypto_aes_mode_context.gcm),
2623                                                       (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2624                                                       input + message_len, icv_len,
2625                                                       NX_CRYPTO_AES_BLOCK_SIZE);
2626         } break;
2627 
2628         case NX_CRYPTO_ENCRYPT:
2629         {
2630             if (iv_ptr == NX_CRYPTO_NULL ||
2631                 (ctx -> nx_crypto_aes_mode_context.gcm.nx_crypto_gcm_additional_data_len > 0 &&
2632                  ctx -> nx_crypto_aes_mode_context.gcm.nx_crypto_gcm_additional_data == NX_CRYPTO_NULL))
2633             {
2634                 status = NX_CRYPTO_PTR_ERROR;
2635                 break;
2636             }
2637 
2638             icv_len = (method -> nx_crypto_ICV_size_in_bits >> 3);
2639 
2640             if (output_length_in_byte < input_length_in_byte + icv_len)
2641             {
2642                 status = NX_CRYPTO_INVALID_BUFFER_SIZE;
2643                 break;
2644             }
2645 
2646             status = _nx_crypto_gcm_encrypt_init(ctx, &(ctx -> nx_crypto_aes_mode_context.gcm),
2647                                                  (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2648                                                  ctx -> nx_crypto_aes_mode_context.gcm.nx_crypto_gcm_additional_data,
2649                                                  ctx -> nx_crypto_aes_mode_context.gcm.nx_crypto_gcm_additional_data_len,
2650                                                  iv_ptr, NX_CRYPTO_AES_BLOCK_SIZE);
2651 
2652             if (status)
2653             {
2654                 break;
2655             }
2656 
2657             status = _nx_crypto_gcm_encrypt_update(ctx, &(ctx -> nx_crypto_aes_mode_context.gcm),
2658                                                    (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2659                                                    input, output, input_length_in_byte,
2660                                                    NX_CRYPTO_AES_BLOCK_SIZE);
2661 
2662             if (status)
2663             {
2664                 break;
2665             }
2666 
2667             status = _nx_crypto_gcm_encrypt_calculate(ctx, &(ctx -> nx_crypto_aes_mode_context.gcm),
2668                                                       (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2669                                                       output + input_length_in_byte, icv_len,
2670                                                       NX_CRYPTO_AES_BLOCK_SIZE);
2671         } break;
2672 
2673         case NX_CRYPTO_DECRYPT_INITIALIZE:
2674         {
2675             if (iv_ptr == NX_CRYPTO_NULL)
2676             {
2677                 status = NX_CRYPTO_PTR_ERROR;
2678                 break;
2679             }
2680 
2681             status = _nx_crypto_gcm_decrypt_init(ctx, &(ctx -> nx_crypto_aes_mode_context.gcm),
2682                                                  (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2683                                                  input, /* pointers to AAD */
2684                                                  input_length_in_byte, /* length of AAD */
2685                                                  iv_ptr, NX_CRYPTO_AES_BLOCK_SIZE);
2686         } break;
2687 
2688         case NX_CRYPTO_DECRYPT_UPDATE:
2689         {
2690             status = _nx_crypto_gcm_decrypt_update(ctx, &(ctx -> nx_crypto_aes_mode_context.gcm),
2691                                                    (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2692                                                    input, output, input_length_in_byte,
2693                                                    NX_CRYPTO_AES_BLOCK_SIZE);
2694         } break;
2695 
2696         case NX_CRYPTO_DECRYPT_CALCULATE:
2697         {
2698             icv_len = (method -> nx_crypto_ICV_size_in_bits >> 3);
2699             if (input_length_in_byte < icv_len)
2700             {
2701                 status = NX_CRYPTO_INVALID_BUFFER_SIZE;
2702                 break;
2703             }
2704 
2705             status = _nx_crypto_gcm_decrypt_calculate(ctx, &(ctx -> nx_crypto_aes_mode_context.gcm),
2706                                                       (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2707                                                       input, icv_len,
2708                                                       NX_CRYPTO_AES_BLOCK_SIZE);
2709         } break;
2710 
2711         case NX_CRYPTO_ENCRYPT_INITIALIZE:
2712         {
2713             if (iv_ptr == NX_CRYPTO_NULL)
2714             {
2715                 status = NX_CRYPTO_PTR_ERROR;
2716                 break;
2717             }
2718 
2719             status = _nx_crypto_gcm_encrypt_init(ctx, &(ctx -> nx_crypto_aes_mode_context.gcm),
2720                                                  (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2721                                                  input, /* pointers to AAD */
2722                                                  input_length_in_byte, /* length of AAD */
2723                                                  iv_ptr, NX_CRYPTO_AES_BLOCK_SIZE);
2724         } break;
2725 
2726         case NX_CRYPTO_ENCRYPT_UPDATE:
2727         {
2728             status = _nx_crypto_gcm_encrypt_update(ctx, &(ctx -> nx_crypto_aes_mode_context.gcm),
2729                                                    (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2730                                                    input, output, input_length_in_byte,
2731                                                    NX_CRYPTO_AES_BLOCK_SIZE);
2732         } break;
2733 
2734         case NX_CRYPTO_ENCRYPT_CALCULATE:
2735         {
2736             icv_len = (method -> nx_crypto_ICV_size_in_bits >> 3);
2737             if (output_length_in_byte < icv_len)
2738             {
2739                 status = NX_CRYPTO_INVALID_BUFFER_SIZE;
2740                 break;
2741             }
2742 
2743             status = _nx_crypto_gcm_encrypt_calculate(ctx, &(ctx -> nx_crypto_aes_mode_context.gcm),
2744                                                       (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2745                                                       output, icv_len,
2746                                                       NX_CRYPTO_AES_BLOCK_SIZE);
2747         } break;
2748 
2749         case NX_CRYPTO_SET_ADDITIONAL_DATA:
2750         {
2751 
2752             /* Set additonal data pointer.  */
2753             ctx -> nx_crypto_aes_mode_context.gcm.nx_crypto_gcm_additional_data = (VOID *)input;
2754 
2755             /* Set additional data length.  */
2756             ctx -> nx_crypto_aes_mode_context.gcm.nx_crypto_gcm_additional_data_len = input_length_in_byte;
2757 
2758             status = NX_CRYPTO_SUCCESS;
2759         } break;
2760 
2761         default:
2762         {
2763             status = NX_CRYPTO_INVALID_ALGORITHM;
2764         } break;
2765     }
2766 
2767     return(status);
2768 }
2769 
2770 /**************************************************************************/
2771 /*                                                                        */
2772 /*  FUNCTION                                               RELEASE        */
2773 /*                                                                        */
2774 /*    _nx_crypto_method_aes_ctr_operation                 PORTABLE C      */
2775 /*                                                           6.3.0        */
2776 /*  AUTHOR                                                                */
2777 /*                                                                        */
2778 /*    Timothy Stapko, Microsoft Corporation                               */
2779 /*                                                                        */
2780 /*  DESCRIPTION                                                           */
2781 /*                                                                        */
2782 /*    This function encrypts and decrypts a message using                 */
2783 /*    the AES CTR algorithm.                                              */
2784 /*                                                                        */
2785 /*  INPUT                                                                 */
2786 /*                                                                        */
2787 /*    op                                    AES operation                 */
2788 /*    handle                                Crypto handle                 */
2789 /*    method                                Cryption Method Object        */
2790 /*    key                                   Encryption Key                */
2791 /*    key_size_in_bits                      Key size in bits              */
2792 /*    input                                 Input data                    */
2793 /*    input_length_in_byte                  Input data size               */
2794 /*    iv_ptr                                Initial vector                */
2795 /*    output                                Output buffer                 */
2796 /*    output_length_in_byte                 Output buffer size            */
2797 /*    crypto_metadata                       Metadata area                 */
2798 /*    crypto_metadata_size                  Metadata area size            */
2799 /*    packet_ptr                            Pointer to packet             */
2800 /*    nx_crypto_hw_process_callback         Callback function pointer     */
2801 /*                                                                        */
2802 /*  OUTPUT                                                                */
2803 /*                                                                        */
2804 /*    status                                Completion status             */
2805 /*                                                                        */
2806 /*  CALLS                                                                 */
2807 /*                                                                        */
2808 /*    _nx_crypto_ctr_encrypt                Perform CTR mode encryption   */
2809 /*                                                                        */
2810 /*  CALLED BY                                                             */
2811 /*                                                                        */
2812 /*    _nx_crypto_method_aes_operation       Handle AES encrypt or decrypt */
2813 /*    Application Code                                                    */
2814 /*                                                                        */
2815 /*  RELEASE HISTORY                                                       */
2816 /*                                                                        */
2817 /*    DATE              NAME                      DESCRIPTION             */
2818 /*                                                                        */
2819 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
2820 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
2821 /*                                            resulting in version 6.1    */
2822 /*  10-31-2023     Yanwu Cai                Modified comment(s),          */
2823 /*                                            resulting in version 6.3.0  */
2824 /*                                                                        */
2825 /**************************************************************************/
_nx_crypto_method_aes_ctr_operation(UINT op,VOID * handle,struct NX_CRYPTO_METHOD_STRUCT * method,UCHAR * key,NX_CRYPTO_KEY_SIZE key_size_in_bits,UCHAR * input,ULONG input_length_in_byte,UCHAR * iv_ptr,UCHAR * output,ULONG output_length_in_byte,VOID * crypto_metadata,ULONG crypto_metadata_size,VOID * packet_ptr,VOID (* nx_crypto_hw_process_callback)(VOID * packet_ptr,UINT status))2826 NX_CRYPTO_KEEP UINT  _nx_crypto_method_aes_ctr_operation(UINT op,      /* Encrypt, Decrypt, Authenticate */
2827                                                          VOID *handle, /* Crypto handler */
2828                                                          struct NX_CRYPTO_METHOD_STRUCT *method,
2829                                                          UCHAR *key,
2830                                                          NX_CRYPTO_KEY_SIZE key_size_in_bits,
2831                                                          UCHAR *input,
2832                                                          ULONG input_length_in_byte,
2833                                                          UCHAR *iv_ptr,
2834                                                          UCHAR *output,
2835                                                          ULONG output_length_in_byte,
2836                                                          VOID *crypto_metadata,
2837                                                          ULONG crypto_metadata_size,
2838                                                          VOID *packet_ptr,
2839                                                          VOID (*nx_crypto_hw_process_callback)(VOID *packet_ptr, UINT status))
2840 {
2841 
2842 NX_CRYPTO_AES      *ctx;
2843 UINT                status;
2844 
2845     NX_CRYPTO_PARAMETER_NOT_USED(op);
2846     NX_CRYPTO_PARAMETER_NOT_USED(handle);
2847     NX_CRYPTO_PARAMETER_NOT_USED(output_length_in_byte);
2848     NX_CRYPTO_PARAMETER_NOT_USED(packet_ptr);
2849     NX_CRYPTO_PARAMETER_NOT_USED(nx_crypto_hw_process_callback);
2850 
2851     NX_CRYPTO_STATE_CHECK
2852 
2853     /* Verify the metadata address is 4-byte aligned. */
2854     if((method == NX_CRYPTO_NULL) || (crypto_metadata == NX_CRYPTO_NULL) || ((((ULONG)crypto_metadata) & 0x3) != 0))
2855     {
2856         return(NX_CRYPTO_PTR_ERROR);
2857     }
2858 
2859     if(crypto_metadata_size < sizeof(NX_CRYPTO_AES))
2860     {
2861         return(NX_CRYPTO_PTR_ERROR);
2862     }
2863 
2864     ctx = (NX_CRYPTO_AES *)crypto_metadata;
2865 
2866     switch (op)
2867     {
2868         case NX_CRYPTO_ENCRYPT:
2869         /* fallthrough */
2870         case NX_CRYPTO_DECRYPT:
2871         {
2872             status = _nx_crypto_ctr_encrypt_init(&(ctx -> nx_crypto_aes_mode_context.ctr),
2873                                                  iv_ptr, 8, &key[key_size_in_bits >> 3], 4);
2874             if (status)
2875             {
2876                 break;
2877             }
2878 
2879             status = _nx_crypto_ctr_encrypt(ctx, &(ctx -> nx_crypto_aes_mode_context.ctr),
2880                                             (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2881                                             input, output, input_length_in_byte,
2882                                             NX_CRYPTO_AES_BLOCK_SIZE);
2883         } break;
2884 
2885         case NX_CRYPTO_ENCRYPT_INITIALIZE:
2886         /* fallthrough */
2887         case NX_CRYPTO_DECRYPT_INITIALIZE:
2888         {
2889             status = _nx_crypto_ctr_encrypt_init(&(ctx -> nx_crypto_aes_mode_context.ctr),
2890                                                  iv_ptr, 8, input, /* input pointers to nonce */
2891                                                  input_length_in_byte);
2892         } break;
2893 
2894         case NX_CRYPTO_ENCRYPT_UPDATE:
2895         /* fallthrough */
2896         case NX_CRYPTO_DECRYPT_UPDATE:
2897         {
2898             status = _nx_crypto_ctr_encrypt(ctx, &(ctx -> nx_crypto_aes_mode_context.ctr),
2899                                             (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2900                                             input, output, input_length_in_byte,
2901                                             NX_CRYPTO_AES_BLOCK_SIZE);
2902         } break;
2903 
2904         case NX_CRYPTO_ENCRYPT_CALCULATE:
2905         /* fallthrough */
2906         case NX_CRYPTO_DECRYPT_CALCULATE:
2907         {
2908 
2909             /* Nothing to do. */
2910             status = NX_CRYPTO_SUCCESS;
2911         } break;
2912 
2913         default:
2914         {
2915             status = NX_CRYPTO_INVALID_ALGORITHM;
2916         } break;
2917     }
2918 
2919     return status;
2920 }
2921 
2922 /**************************************************************************/
2923 /*                                                                        */
2924 /*  FUNCTION                                               RELEASE        */
2925 /*                                                                        */
2926 /*    _nx_crypto_method_aes_xcbc_operation                PORTABLE C      */
2927 /*                                                           6.3.0        */
2928 /*  AUTHOR                                                                */
2929 /*                                                                        */
2930 /*    Timothy Stapko, Microsoft Corporation                               */
2931 /*                                                                        */
2932 /*  DESCRIPTION                                                           */
2933 /*                                                                        */
2934 /*    This function encrypts and decrypts a message using                 */
2935 /*    the AES XCBC algorithm.                                             */
2936 /*                                                                        */
2937 /*  INPUT                                                                 */
2938 /*                                                                        */
2939 /*    op                                    AES operation                 */
2940 /*    handle                                Crypto handle                 */
2941 /*    method                                Cryption Method Object        */
2942 /*    key                                   Encryption Key                */
2943 /*    key_size_in_bits                      Key size in bits              */
2944 /*    input                                 Input data                    */
2945 /*    input_length_in_byte                  Input data size               */
2946 /*    iv_ptr                                Initial vector                */
2947 /*    output                                Output buffer                 */
2948 /*    output_length_in_byte                 Output buffer size            */
2949 /*    crypto_metadata                       Metadata area                 */
2950 /*    crypto_metadata_size                  Metadata area size            */
2951 /*    packet_ptr                            Pointer to packet             */
2952 /*    nx_crypto_hw_process_callback         Callback function pointer     */
2953 /*                                                                        */
2954 /*  OUTPUT                                                                */
2955 /*                                                                        */
2956 /*    status                                Completion status             */
2957 /*                                                                        */
2958 /*  CALLS                                                                 */
2959 /*                                                                        */
2960 /*    _nx_crypto_xcbc_mac                   Perform XCBC mode             */
2961 /*                                                                        */
2962 /*  CALLED BY                                                             */
2963 /*                                                                        */
2964 /*    _nx_crypto_method_aes_operation       Handle AES encrypt or decrypt */
2965 /*    Application Code                                                    */
2966 /*                                                                        */
2967 /*  RELEASE HISTORY                                                       */
2968 /*                                                                        */
2969 /*    DATE              NAME                      DESCRIPTION             */
2970 /*                                                                        */
2971 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
2972 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
2973 /*                                            resulting in version 6.1    */
2974 /*  10-31-2023     Yanwu Cai                Modified comment(s),          */
2975 /*                                            resulting in version 6.3.0  */
2976 /*                                                                        */
2977 /**************************************************************************/
_nx_crypto_method_aes_xcbc_operation(UINT op,VOID * handle,struct NX_CRYPTO_METHOD_STRUCT * method,UCHAR * key,NX_CRYPTO_KEY_SIZE key_size_in_bits,UCHAR * input,ULONG input_length_in_byte,UCHAR * iv_ptr,UCHAR * output,ULONG output_length_in_byte,VOID * crypto_metadata,ULONG crypto_metadata_size,VOID * packet_ptr,VOID (* nx_crypto_hw_process_callback)(VOID * packet_ptr,UINT status))2978 NX_CRYPTO_KEEP UINT  _nx_crypto_method_aes_xcbc_operation(UINT op,      /* Encrypt, Decrypt, Authenticate */
2979                                                           VOID *handle, /* Crypto handler */
2980                                                           struct NX_CRYPTO_METHOD_STRUCT *method,
2981                                                           UCHAR *key,
2982                                                           NX_CRYPTO_KEY_SIZE key_size_in_bits,
2983                                                           UCHAR *input,
2984                                                           ULONG input_length_in_byte,
2985                                                           UCHAR *iv_ptr,
2986                                                           UCHAR *output,
2987                                                           ULONG output_length_in_byte,
2988                                                           VOID *crypto_metadata,
2989                                                           ULONG crypto_metadata_size,
2990                                                           VOID *packet_ptr,
2991                                                           VOID (*nx_crypto_hw_process_callback)(VOID *packet_ptr, UINT status))
2992 {
2993 
2994 NX_CRYPTO_AES  *ctx;
2995 UINT            status;
2996 
2997     NX_CRYPTO_PARAMETER_NOT_USED(op);
2998     NX_CRYPTO_PARAMETER_NOT_USED(handle);
2999     NX_CRYPTO_PARAMETER_NOT_USED(iv_ptr);
3000     NX_CRYPTO_PARAMETER_NOT_USED(output_length_in_byte);
3001     NX_CRYPTO_PARAMETER_NOT_USED(packet_ptr);
3002     NX_CRYPTO_PARAMETER_NOT_USED(nx_crypto_hw_process_callback);
3003 
3004     NX_CRYPTO_STATE_CHECK
3005 
3006     /* Verify the metadata address is 4-byte aligned. */
3007     if((method == NX_CRYPTO_NULL) || (key == NX_CRYPTO_NULL) || (crypto_metadata == NX_CRYPTO_NULL) || ((((ULONG)crypto_metadata) & 0x3) != 0))
3008     {
3009         return(NX_CRYPTO_PTR_ERROR);
3010     }
3011 
3012     if(crypto_metadata_size < sizeof(NX_CRYPTO_AES))
3013     {
3014         return(NX_CRYPTO_PTR_ERROR);
3015     }
3016 
3017     ctx = (NX_CRYPTO_AES *)crypto_metadata;
3018 
3019     status = _nx_crypto_xcbc_mac(ctx,
3020                                  (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
3021                                  (UINT (*)(VOID *, UCHAR *, UINT))_nx_crypto_aes_key_set,
3022                                  key, key_size_in_bits,
3023                                  input, output, input_length_in_byte,
3024                                  NX_CRYPTO_NULL, NX_CRYPTO_AUTHENTICATION_ICV_TRUNC_BITS >> 3,
3025                                  NX_CRYPTO_AES_BLOCK_SIZE);
3026 
3027     return status;
3028 }
3029