make app_queue 1.2 jump compliant (issue #5580)
[asterisk/asterisk.git] / aeskey.c
1 /*
2  ---------------------------------------------------------------------------
3  Copyright (c) 2003, Dr Brian Gladman <brg@gladman.me.uk>, Worcester, UK.
4  All rights reserved.
5
6  LICENSE TERMS
7
8  The free distribution and use of this software in both source and binary
9  form is allowed (with or without changes) provided that:
10
11    1. distributions of this source code include the above copyright
12       notice, this list of conditions and the following disclaimer;
13
14    2. distributions in binary form include the above copyright
15       notice, this list of conditions and the following disclaimer
16       in the documentation and/or other associated materials;
17
18    3. the copyright holder's name is not used to endorse products
19       built using this software without specific written permission.
20
21  ALTERNATIVELY, provided that this notice is retained in full, this product
22  may be distributed under the terms of the GNU General Public License (GPL),
23  in which case the provisions of the GPL apply INSTEAD OF those given above.
24
25  DISCLAIMER
26
27  This software is provided 'as is' with no explicit or implied warranties
28  in respect of its properties, including, but not limited to, correctness
29  and/or fitness for purpose.
30  ---------------------------------------------------------------------------
31  Issue Date: 26/08/2003
32
33 */
34 /*! \file
35 \brief  This file contains the code for implementing the key schedule for AES
36  (Rijndael) for block and key sizes of 16, 24, and 32 bytes. See aesopt.h
37  for further details including optimisation.
38 */
39
40 #include "aesopt.h"
41
42 #if defined(__cplusplus)
43 extern "C"
44 {
45 #endif
46
47 /* Initialise the key schedule from the user supplied key. The key
48    length can be specified in bytes, with legal values of 16, 24
49    and 32, or in bits, with legal values of 128, 192 and 256. These
50    values correspond with Nk values of 4, 6 and 8 respectively.
51
52    The following macros implement a single cycle in the key
53    schedule generation process. The number of cycles needed
54    for each cx->n_col and nk value is:
55
56     nk =             4  5  6  7  8
57     ------------------------------
58     cx->n_col = 4   10  9  8  7  7
59     cx->n_col = 5   14 11 10  9  9
60     cx->n_col = 6   19 15 12 11 11
61     cx->n_col = 7   21 19 16 13 14
62     cx->n_col = 8   29 23 19 17 14
63 */
64
65 #define ke4(k,i) \
66 {   k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[4*(i)+5] = ss[1] ^= ss[0]; \
67     k[4*(i)+6] = ss[2] ^= ss[1]; k[4*(i)+7] = ss[3] ^= ss[2]; \
68 }
69 #define kel4(k,i) \
70 {   k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[4*(i)+5] = ss[1] ^= ss[0]; \
71     k[4*(i)+6] = ss[2] ^= ss[1]; k[4*(i)+7] = ss[3] ^= ss[2]; \
72 }
73
74 #define ke6(k,i) \
75 {   k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[6*(i)+ 7] = ss[1] ^= ss[0]; \
76     k[6*(i)+ 8] = ss[2] ^= ss[1]; k[6*(i)+ 9] = ss[3] ^= ss[2]; \
77     k[6*(i)+10] = ss[4] ^= ss[3]; k[6*(i)+11] = ss[5] ^= ss[4]; \
78 }
79 #define kel6(k,i) \
80 {   k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[6*(i)+ 7] = ss[1] ^= ss[0]; \
81     k[6*(i)+ 8] = ss[2] ^= ss[1]; k[6*(i)+ 9] = ss[3] ^= ss[2]; \
82 }
83
84 #define ke8(k,i) \
85 {   k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[8*(i)+ 9] = ss[1] ^= ss[0]; \
86     k[8*(i)+10] = ss[2] ^= ss[1]; k[8*(i)+11] = ss[3] ^= ss[2]; \
87     k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); k[8*(i)+13] = ss[5] ^= ss[4]; \
88     k[8*(i)+14] = ss[6] ^= ss[5]; k[8*(i)+15] = ss[7] ^= ss[6]; \
89 }
90 #define kel8(k,i) \
91 {   k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[8*(i)+ 9] = ss[1] ^= ss[0]; \
92     k[8*(i)+10] = ss[2] ^= ss[1]; k[8*(i)+11] = ss[3] ^= ss[2]; \
93 }
94
95 #if defined(ENCRYPTION_KEY_SCHEDULE)
96
97 #if defined(AES_128) || defined(AES_VAR)
98
99 aes_rval aes_encrypt_key128(const void *in_key, aes_encrypt_ctx cx[1])
100 {   aes_32t    ss[4];
101
102     cx->ks[0] = ss[0] = word_in(in_key, 0);
103     cx->ks[1] = ss[1] = word_in(in_key, 1);
104     cx->ks[2] = ss[2] = word_in(in_key, 2);
105     cx->ks[3] = ss[3] = word_in(in_key, 3);
106
107 #if ENC_UNROLL == NONE
108     {   aes_32t i;
109
110         for(i = 0; i < ((11 * N_COLS - 1) / 4); ++i)
111             ke4(cx->ks, i);
112     }
113 #else
114     ke4(cx->ks, 0);  ke4(cx->ks, 1);
115     ke4(cx->ks, 2);  ke4(cx->ks, 3);
116     ke4(cx->ks, 4);  ke4(cx->ks, 5);
117     ke4(cx->ks, 6);  ke4(cx->ks, 7);
118     ke4(cx->ks, 8); kel4(cx->ks, 9);
119 #endif
120
121     /* cx->ks[45] ^ cx->ks[52] ^ cx->ks[53] is zero for a 256 bit       */
122     /* key and must be non-zero for 128 and 192 bits keys   */
123     cx->ks[53] = cx->ks[45] = 0;
124     cx->ks[52] = 10;
125 #ifdef AES_ERR_CHK
126     return aes_good;
127 #endif
128 }
129
130 #endif
131
132 #if defined(AES_192) || defined(AES_VAR)
133
134 aes_rval aes_encrypt_key192(const void *in_key, aes_encrypt_ctx cx[1])
135 {   aes_32t    ss[6];
136
137     cx->ks[0] = ss[0] = word_in(in_key, 0);
138     cx->ks[1] = ss[1] = word_in(in_key, 1);
139     cx->ks[2] = ss[2] = word_in(in_key, 2);
140     cx->ks[3] = ss[3] = word_in(in_key, 3);
141     cx->ks[4] = ss[4] = word_in(in_key, 4);
142     cx->ks[5] = ss[5] = word_in(in_key, 5);
143
144 #if ENC_UNROLL == NONE
145     {   aes_32t i;
146
147         for(i = 0; i < (13 * N_COLS - 1) / 6; ++i)
148             ke6(cx->ks, i);
149     }
150 #else
151     ke6(cx->ks, 0);  ke6(cx->ks, 1);
152     ke6(cx->ks, 2);  ke6(cx->ks, 3);
153     ke6(cx->ks, 4);  ke6(cx->ks, 5);
154     ke6(cx->ks, 6); kel6(cx->ks, 7);
155 #endif
156
157     /* cx->ks[45] ^ cx->ks[52] ^ cx->ks[53] is zero for a 256 bit       */
158     /* key and must be non-zero for 128 and 192 bits keys   */
159     cx->ks[53] = cx->ks[45];
160     cx->ks[52] = 12;
161 #ifdef AES_ERR_CHK
162     return aes_good;
163 #endif
164 }
165
166 #endif
167
168 #if defined(AES_256) || defined(AES_VAR)
169
170 aes_rval aes_encrypt_key256(const void *in_key, aes_encrypt_ctx cx[1])
171 {   aes_32t    ss[8];
172
173     cx->ks[0] = ss[0] = word_in(in_key, 0);
174     cx->ks[1] = ss[1] = word_in(in_key, 1);
175     cx->ks[2] = ss[2] = word_in(in_key, 2);
176     cx->ks[3] = ss[3] = word_in(in_key, 3);
177     cx->ks[4] = ss[4] = word_in(in_key, 4);
178     cx->ks[5] = ss[5] = word_in(in_key, 5);
179     cx->ks[6] = ss[6] = word_in(in_key, 6);
180     cx->ks[7] = ss[7] = word_in(in_key, 7);
181
182 #if ENC_UNROLL == NONE
183     {   aes_32t i;
184
185         for(i = 0; i < (15 * N_COLS - 1) / 8; ++i)
186             ke8(cx->ks,  i);
187     }
188 #else
189     ke8(cx->ks, 0); ke8(cx->ks, 1);
190     ke8(cx->ks, 2); ke8(cx->ks, 3);
191     ke8(cx->ks, 4); ke8(cx->ks, 5);
192     kel8(cx->ks, 6);
193 #endif
194 #ifdef AES_ERR_CHK
195     return aes_good;
196 #endif
197 }
198
199 #endif
200
201 #if defined(AES_VAR)
202
203 aes_rval aes_encrypt_key(const void *in_key, int key_len, aes_encrypt_ctx cx[1])
204 {
205     switch(key_len)
206     {
207 #ifdef AES_ERR_CHK
208     case 16: case 128: return aes_encrypt_key128(in_key, cx);
209     case 24: case 192: return aes_encrypt_key192(in_key, cx);
210     case 32: case 256: return aes_encrypt_key256(in_key, cx);
211     default: return aes_error;
212 #else
213     case 16: case 128: aes_encrypt_key128(in_key, cx); return;
214     case 24: case 192: aes_encrypt_key192(in_key, cx); return;
215     case 32: case 256: aes_encrypt_key256(in_key, cx); return;
216 #endif
217     }
218 }
219
220 #endif
221
222 #endif
223
224 #if defined(DECRYPTION_KEY_SCHEDULE)
225
226 #if DEC_ROUND == NO_TABLES
227 #define ff(x)   (x)
228 #else
229 #define ff(x)   inv_mcol(x)
230 #ifdef  dec_imvars
231 #define d_vars  dec_imvars
232 #endif
233 #endif
234
235 #if 1
236 #define kdf4(k,i) \
237 {   ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; ss[1] = ss[1] ^ ss[3]; ss[2] = ss[2] ^ ss[3]; ss[3] = ss[3]; \
238     ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; \
239     ss[4] ^= k[4*(i)];   k[4*(i)+4] = ff(ss[4]); ss[4] ^= k[4*(i)+1]; k[4*(i)+5] = ff(ss[4]); \
240     ss[4] ^= k[4*(i)+2]; k[4*(i)+6] = ff(ss[4]); ss[4] ^= k[4*(i)+3]; k[4*(i)+7] = ff(ss[4]); \
241 }
242 #define kd4(k,i) \
243 {   ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; ss[4] = ff(ss[4]); \
244     k[4*(i)+4] = ss[4] ^= k[4*(i)]; k[4*(i)+5] = ss[4] ^= k[4*(i)+1]; \
245     k[4*(i)+6] = ss[4] ^= k[4*(i)+2]; k[4*(i)+7] = ss[4] ^= k[4*(i)+3]; \
246 }
247 #define kdl4(k,i) \
248 {   ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; \
249     k[4*(i)+4] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; k[4*(i)+5] = ss[1] ^ ss[3]; \
250     k[4*(i)+6] = ss[0]; k[4*(i)+7] = ss[1]; \
251 }
252 #else
253 #define kdf4(k,i) \
254 {   ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[4*(i)+ 4] = ff(ss[0]); ss[1] ^= ss[0]; k[4*(i)+ 5] = ff(ss[1]); \
255     ss[2] ^= ss[1]; k[4*(i)+ 6] = ff(ss[2]); ss[3] ^= ss[2]; k[4*(i)+ 7] = ff(ss[3]); \
256 }
257 #define kd4(k,i) \
258 {   ss[4] = ls_box(ss[3],3) ^ t_use(r,c)[i]; \
259     ss[0] ^= ss[4]; ss[4] = ff(ss[4]); k[4*(i)+ 4] = ss[4] ^= k[4*(i)]; \
260     ss[1] ^= ss[0]; k[4*(i)+ 5] = ss[4] ^= k[4*(i)+ 1]; \
261     ss[2] ^= ss[1]; k[4*(i)+ 6] = ss[4] ^= k[4*(i)+ 2]; \
262     ss[3] ^= ss[2]; k[4*(i)+ 7] = ss[4] ^= k[4*(i)+ 3]; \
263 }
264 #define kdl4(k,i) \
265 {   ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[4*(i)+ 4] = ss[0]; ss[1] ^= ss[0]; k[4*(i)+ 5] = ss[1]; \
266     ss[2] ^= ss[1]; k[4*(i)+ 6] = ss[2]; ss[3] ^= ss[2]; k[4*(i)+ 7] = ss[3]; \
267 }
268 #endif
269
270 #define kdf6(k,i) \
271 {   ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[6*(i)+ 6] = ff(ss[0]); ss[1] ^= ss[0]; k[6*(i)+ 7] = ff(ss[1]); \
272     ss[2] ^= ss[1]; k[6*(i)+ 8] = ff(ss[2]); ss[3] ^= ss[2]; k[6*(i)+ 9] = ff(ss[3]); \
273     ss[4] ^= ss[3]; k[6*(i)+10] = ff(ss[4]); ss[5] ^= ss[4]; k[6*(i)+11] = ff(ss[5]); \
274 }
275 #define kd6(k,i) \
276 {   ss[6] = ls_box(ss[5],3) ^ t_use(r,c)[i]; \
277     ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[6*(i)+ 6] = ss[6] ^= k[6*(i)]; \
278     ss[1] ^= ss[0]; k[6*(i)+ 7] = ss[6] ^= k[6*(i)+ 1]; \
279     ss[2] ^= ss[1]; k[6*(i)+ 8] = ss[6] ^= k[6*(i)+ 2]; \
280     ss[3] ^= ss[2]; k[6*(i)+ 9] = ss[6] ^= k[6*(i)+ 3]; \
281     ss[4] ^= ss[3]; k[6*(i)+10] = ss[6] ^= k[6*(i)+ 4]; \
282     ss[5] ^= ss[4]; k[6*(i)+11] = ss[6] ^= k[6*(i)+ 5]; \
283 }
284 #define kdl6(k,i) \
285 {   ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[6*(i)+ 6] = ss[0]; ss[1] ^= ss[0]; k[6*(i)+ 7] = ss[1]; \
286     ss[2] ^= ss[1]; k[6*(i)+ 8] = ss[2]; ss[3] ^= ss[2]; k[6*(i)+ 9] = ss[3]; \
287 }
288
289 #define kdf8(k,i) \
290 {   ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[8*(i)+ 8] = ff(ss[0]); ss[1] ^= ss[0]; k[8*(i)+ 9] = ff(ss[1]); \
291     ss[2] ^= ss[1]; k[8*(i)+10] = ff(ss[2]); ss[3] ^= ss[2]; k[8*(i)+11] = ff(ss[3]); \
292     ss[4] ^= ls_box(ss[3],0); k[8*(i)+12] = ff(ss[4]); ss[5] ^= ss[4]; k[8*(i)+13] = ff(ss[5]); \
293     ss[6] ^= ss[5]; k[8*(i)+14] = ff(ss[6]); ss[7] ^= ss[6]; k[8*(i)+15] = ff(ss[7]); \
294 }
295 #define kd8(k,i) \
296 {   aes_32t g = ls_box(ss[7],3) ^ t_use(r,c)[i]; \
297     ss[0] ^= g; g = ff(g); k[8*(i)+ 8] = g ^= k[8*(i)]; \
298     ss[1] ^= ss[0]; k[8*(i)+ 9] = g ^= k[8*(i)+ 1]; \
299     ss[2] ^= ss[1]; k[8*(i)+10] = g ^= k[8*(i)+ 2]; \
300     ss[3] ^= ss[2]; k[8*(i)+11] = g ^= k[8*(i)+ 3]; \
301     g = ls_box(ss[3],0); \
302     ss[4] ^= g; g = ff(g); k[8*(i)+12] = g ^= k[8*(i)+ 4]; \
303     ss[5] ^= ss[4]; k[8*(i)+13] = g ^= k[8*(i)+ 5]; \
304     ss[6] ^= ss[5]; k[8*(i)+14] = g ^= k[8*(i)+ 6]; \
305     ss[7] ^= ss[6]; k[8*(i)+15] = g ^= k[8*(i)+ 7]; \
306 }
307 #define kdl8(k,i) \
308 {   ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[8*(i)+ 8] = ss[0]; ss[1] ^= ss[0]; k[8*(i)+ 9] = ss[1]; \
309     ss[2] ^= ss[1]; k[8*(i)+10] = ss[2]; ss[3] ^= ss[2]; k[8*(i)+11] = ss[3]; \
310 }
311
312 #if defined(AES_128) || defined(AES_VAR)
313
314 aes_rval aes_decrypt_key128(const void *in_key, aes_decrypt_ctx cx[1])
315 {   aes_32t    ss[5];
316 #ifdef  d_vars
317         d_vars;
318 #endif
319     cx->ks[0] = ss[0] = word_in(in_key, 0);
320     cx->ks[1] = ss[1] = word_in(in_key, 1);
321     cx->ks[2] = ss[2] = word_in(in_key, 2);
322     cx->ks[3] = ss[3] = word_in(in_key, 3);
323
324 #if DEC_UNROLL == NONE
325     {   aes_32t i;
326
327         for(i = 0; i < (11 * N_COLS - 1) / 4; ++i)
328             ke4(cx->ks, i);
329 #if !(DEC_ROUND == NO_TABLES)
330         for(i = N_COLS; i < 10 * N_COLS; ++i)
331             cx->ks[i] = inv_mcol(cx->ks[i]);
332 #endif
333     }
334 #else
335     kdf4(cx->ks, 0);  kd4(cx->ks, 1);
336      kd4(cx->ks, 2);  kd4(cx->ks, 3);
337      kd4(cx->ks, 4);  kd4(cx->ks, 5);
338      kd4(cx->ks, 6);  kd4(cx->ks, 7);
339      kd4(cx->ks, 8); kdl4(cx->ks, 9);
340 #endif
341
342     /* cx->ks[45] ^ cx->ks[52] ^ cx->ks[53] is zero for a 256 bit       */
343     /* key and must be non-zero for 128 and 192 bits keys   */
344     cx->ks[53] = cx->ks[45] = 0;
345     cx->ks[52] = 10;
346 #ifdef AES_ERR_CHK
347     return aes_good;
348 #endif
349 }
350
351 #endif
352
353 #if defined(AES_192) || defined(AES_VAR)
354
355 aes_rval aes_decrypt_key192(const void *in_key, aes_decrypt_ctx cx[1])
356 {   aes_32t    ss[7];
357 #ifdef  d_vars
358         d_vars;
359 #endif
360     cx->ks[0] = ss[0] = word_in(in_key, 0);
361     cx->ks[1] = ss[1] = word_in(in_key, 1);
362     cx->ks[2] = ss[2] = word_in(in_key, 2);
363     cx->ks[3] = ss[3] = word_in(in_key, 3);
364
365 #if DEC_UNROLL == NONE
366     cx->ks[4] = ss[4] = word_in(in_key, 4);
367     cx->ks[5] = ss[5] = word_in(in_key, 5);
368     {   aes_32t i;
369
370         for(i = 0; i < (13 * N_COLS - 1) / 6; ++i)
371             ke6(cx->ks, i);
372 #if !(DEC_ROUND == NO_TABLES)
373         for(i = N_COLS; i < 12 * N_COLS; ++i)
374             cx->ks[i] = inv_mcol(cx->ks[i]);
375 #endif
376     }
377 #else
378     cx->ks[4] = ff(ss[4] = word_in(in_key, 4));
379     cx->ks[5] = ff(ss[5] = word_in(in_key, 5));
380     kdf6(cx->ks, 0); kd6(cx->ks, 1);
381     kd6(cx->ks, 2);  kd6(cx->ks, 3);
382     kd6(cx->ks, 4);  kd6(cx->ks, 5);
383     kd6(cx->ks, 6); kdl6(cx->ks, 7);
384 #endif
385
386     /* cx->ks[45] ^ cx->ks[52] ^ cx->ks[53] is zero for a 256 bit       */
387     /* key and must be non-zero for 128 and 192 bits keys   */
388     cx->ks[53] = cx->ks[45];
389     cx->ks[52] = 12;
390 #ifdef AES_ERR_CHK
391     return aes_good;
392 #endif
393 }
394
395 #endif
396
397 #if defined(AES_256) || defined(AES_VAR)
398
399 aes_rval aes_decrypt_key256(const void *in_key, aes_decrypt_ctx cx[1])
400 {   aes_32t    ss[8];
401 #ifdef  d_vars
402         d_vars;
403 #endif
404     cx->ks[0] = ss[0] = word_in(in_key, 0);
405     cx->ks[1] = ss[1] = word_in(in_key, 1);
406     cx->ks[2] = ss[2] = word_in(in_key, 2);
407     cx->ks[3] = ss[3] = word_in(in_key, 3);
408
409 #if DEC_UNROLL == NONE
410     cx->ks[4] = ss[4] = word_in(in_key, 4);
411     cx->ks[5] = ss[5] = word_in(in_key, 5);
412     cx->ks[6] = ss[6] = word_in(in_key, 6);
413     cx->ks[7] = ss[7] = word_in(in_key, 7);
414     {   aes_32t i;
415
416         for(i = 0; i < (15 * N_COLS - 1) / 8; ++i)
417             ke8(cx->ks,  i);
418 #if !(DEC_ROUND == NO_TABLES)
419         for(i = N_COLS; i < 14 * N_COLS; ++i)
420             cx->ks[i] = inv_mcol(cx->ks[i]);
421 #endif
422     }
423 #else
424     cx->ks[4] = ff(ss[4] = word_in(in_key, 4));
425     cx->ks[5] = ff(ss[5] = word_in(in_key, 5));
426     cx->ks[6] = ff(ss[6] = word_in(in_key, 6));
427     cx->ks[7] = ff(ss[7] = word_in(in_key, 7));
428     kdf8(cx->ks, 0); kd8(cx->ks, 1);
429     kd8(cx->ks, 2);  kd8(cx->ks, 3);
430     kd8(cx->ks, 4);  kd8(cx->ks, 5);
431     kdl8(cx->ks, 6);
432 #endif
433 #ifdef AES_ERR_CHK
434     return aes_good;
435 #endif
436 }
437
438 #endif
439
440 #if defined(AES_VAR)
441
442 aes_rval aes_decrypt_key(const void *in_key, int key_len, aes_decrypt_ctx cx[1])
443 {
444     switch(key_len)
445     {
446 #ifdef AES_ERR_CHK
447     case 16: case 128: return aes_decrypt_key128(in_key, cx);
448     case 24: case 192: return aes_decrypt_key192(in_key, cx);
449     case 32: case 256: return aes_decrypt_key256(in_key, cx);
450     default: return aes_error;
451 #else
452     case 16: case 128: aes_decrypt_key128(in_key, cx); return;
453     case 24: case 192: aes_decrypt_key192(in_key, cx); return;
454     case 32: case 256: aes_decrypt_key256(in_key, cx); return;
455 #endif
456     }
457 }
458
459 #endif
460
461 #endif
462
463 #if defined(__cplusplus)
464 }
465 #endif