1 /*
2 * padding.c: miscellaneous padding functions
3 *
4 * Copyright (C) 2001, 2002 Juha Yrjölä <juha.yrjola@iki.fi>
5 * Copyright (C) 2003 - 2007 Nils Larsch <larsch@trustcenter.de>
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22 #if HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #ifdef ENABLE_OPENSSL
27 #include <openssl/evp.h>
28 #include <openssl/rand.h>
29 #include <openssl/sha.h>
30 #endif
31
32 #include <string.h>
33 #include <stdlib.h>
34
35 #include "internal.h"
36
37 /* TODO doxygen comments */
38
39 /*
40 * Prefixes for pkcs-v1 signatures
41 */
42 static const u8 hdr_md5[] = {
43 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7,
44 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10
45 };
46 static const u8 hdr_sha1[] = {
47 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a,
48 0x05, 0x00, 0x04, 0x14
49 };
50 static const u8 hdr_sha256[] = {
51 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65,
52 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
53 };
54 static const u8 hdr_sha384[] = {
55 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65,
56 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30
57 };
58 static const u8 hdr_sha512[] = {
59 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65,
60 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40
61 };
62 static const u8 hdr_sha224[] = {
63 0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65,
64 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c
65 };
66 static const u8 hdr_ripemd160[] = {
67 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03, 0x02, 0x01,
68 0x05, 0x00, 0x04, 0x14
69 };
70
71
72 static const struct digest_info_prefix {
73 unsigned int algorithm;
74 const u8 * hdr;
75 size_t hdr_len;
76 size_t hash_len;
77 } digest_info_prefix[] = {
78 { SC_ALGORITHM_RSA_HASH_NONE, NULL, 0, 0 },
79 { SC_ALGORITHM_RSA_HASH_MD5, hdr_md5, sizeof(hdr_md5), 16 },
80 { SC_ALGORITHM_RSA_HASH_SHA1, hdr_sha1, sizeof(hdr_sha1), 20 },
81 { SC_ALGORITHM_RSA_HASH_SHA256, hdr_sha256, sizeof(hdr_sha256), 32 },
82 { SC_ALGORITHM_RSA_HASH_SHA384, hdr_sha384, sizeof(hdr_sha384), 48 },
83 { SC_ALGORITHM_RSA_HASH_SHA512, hdr_sha512, sizeof(hdr_sha512), 64 },
84 { SC_ALGORITHM_RSA_HASH_SHA224, hdr_sha224, sizeof(hdr_sha224), 28 },
85 { SC_ALGORITHM_RSA_HASH_RIPEMD160,hdr_ripemd160, sizeof(hdr_ripemd160), 20 },
86 { SC_ALGORITHM_RSA_HASH_MD5_SHA1, NULL, 0, 36 },
87 { 0, NULL, 0, 0 }
88 };
89
90 /* add/remove pkcs1 BT01 padding */
91
sc_pkcs1_add_01_padding(const u8 * in,size_t in_len,u8 * out,size_t * out_len,size_t mod_length)92 static int sc_pkcs1_add_01_padding(const u8 *in, size_t in_len,
93 u8 *out, size_t *out_len, size_t mod_length)
94 {
95 size_t i;
96
97 if (*out_len < mod_length)
98 return SC_ERROR_BUFFER_TOO_SMALL;
99 if (in_len + 11 > mod_length)
100 return SC_ERROR_INVALID_ARGUMENTS;
101 i = mod_length - in_len;
102 memmove(out + i, in, in_len);
103 *out++ = 0x00;
104 *out++ = 0x01;
105
106 memset(out, 0xFF, i - 3);
107 out += i - 3;
108 *out = 0x00;
109
110 *out_len = mod_length;
111 return SC_SUCCESS;
112 }
113
114 int
sc_pkcs1_strip_01_padding(struct sc_context * ctx,const u8 * in_dat,size_t in_len,u8 * out,size_t * out_len)115 sc_pkcs1_strip_01_padding(struct sc_context *ctx, const u8 *in_dat, size_t in_len,
116 u8 *out, size_t *out_len)
117 {
118 const u8 *tmp = in_dat;
119 size_t len;
120
121 if (in_dat == NULL || in_len < 10)
122 return SC_ERROR_INTERNAL;
123 /* skip leading zero byte */
124 if (*tmp == 0) {
125 tmp++;
126 in_len--;
127 }
128 len = in_len;
129 if (*tmp != 0x01)
130 return SC_ERROR_WRONG_PADDING;
131 for (tmp++, len--; *tmp == 0xff && len != 0; tmp++, len--)
132 ;
133 if (!len || (in_len - len) < 9 || *tmp++ != 0x00)
134 return SC_ERROR_WRONG_PADDING;
135 len--;
136 if (out == NULL)
137 /* just check the padding */
138 return SC_SUCCESS;
139 if (*out_len < len)
140 return SC_ERROR_INTERNAL;
141 memmove(out, tmp, len);
142 *out_len = len;
143 return SC_SUCCESS;
144 }
145
146
147 /* remove pkcs1 BT02 padding (adding BT02 padding is currently not
148 * needed/implemented) */
149 int
sc_pkcs1_strip_02_padding(sc_context_t * ctx,const u8 * data,size_t len,u8 * out,size_t * out_len)150 sc_pkcs1_strip_02_padding(sc_context_t *ctx, const u8 *data, size_t len, u8 *out, size_t *out_len)
151 {
152 unsigned int n = 0;
153
154 LOG_FUNC_CALLED(ctx);
155 if (data == NULL || len < 3)
156 LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL);
157
158 /* skip leading zero byte */
159 if (*data == 0) {
160 data++;
161 len--;
162 }
163 if (data[0] != 0x02)
164 LOG_FUNC_RETURN(ctx, SC_ERROR_WRONG_PADDING);
165 /* skip over padding bytes */
166 for (n = 1; n < len && data[n]; n++)
167 ;
168 /* Must be at least 8 pad bytes */
169 if (n >= len || n < 9)
170 LOG_FUNC_RETURN(ctx, SC_ERROR_WRONG_PADDING);
171 n++;
172 if (out == NULL)
173 /* just check the padding */
174 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
175
176 /* Now move decrypted contents to head of buffer */
177 if (*out_len < len - n)
178 LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL);
179 *out_len = len - n;
180 memmove(out, data + n, *out_len);
181
182 sc_log(ctx, "stripped output(%"SC_FORMAT_LEN_SIZE_T"u): %s", len - n,
183 sc_dump_hex(out, len - n));
184 LOG_FUNC_RETURN(ctx, len - n);
185 }
186
187 /* add/remove DigestInfo prefix */
sc_pkcs1_add_digest_info_prefix(unsigned int algorithm,const u8 * in,size_t in_len,u8 * out,size_t * out_len)188 static int sc_pkcs1_add_digest_info_prefix(unsigned int algorithm,
189 const u8 *in, size_t in_len, u8 *out, size_t *out_len)
190 {
191 int i;
192
193 for (i = 0; digest_info_prefix[i].algorithm != 0; i++) {
194 if (algorithm == digest_info_prefix[i].algorithm) {
195 const u8 *hdr = digest_info_prefix[i].hdr;
196 size_t hdr_len = digest_info_prefix[i].hdr_len,
197 hash_len = digest_info_prefix[i].hash_len;
198
199 if (in_len != hash_len || *out_len < (hdr_len + hash_len))
200 return SC_ERROR_INTERNAL;
201
202 memmove(out + hdr_len, in, hash_len);
203 memmove(out, hdr, hdr_len);
204 *out_len = hdr_len + hash_len;
205
206 return SC_SUCCESS;
207 }
208 }
209
210 return SC_ERROR_INTERNAL;
211 }
212
sc_pkcs1_strip_digest_info_prefix(unsigned int * algorithm,const u8 * in_dat,size_t in_len,u8 * out_dat,size_t * out_len)213 int sc_pkcs1_strip_digest_info_prefix(unsigned int *algorithm,
214 const u8 *in_dat, size_t in_len, u8 *out_dat, size_t *out_len)
215 {
216 int i;
217
218 for (i = 0; digest_info_prefix[i].algorithm != 0; i++) {
219 size_t hdr_len = digest_info_prefix[i].hdr_len,
220 hash_len = digest_info_prefix[i].hash_len;
221 const u8 *hdr = digest_info_prefix[i].hdr;
222
223 if (in_len == (hdr_len + hash_len) &&
224 !memcmp(in_dat, hdr, hdr_len)) {
225 if (algorithm)
226 *algorithm = digest_info_prefix[i].algorithm;
227 if (out_dat == NULL)
228 /* just check the DigestInfo prefix */
229 return SC_SUCCESS;
230 if (*out_len < hash_len)
231 return SC_ERROR_INTERNAL;
232 memmove(out_dat, in_dat + hdr_len, hash_len);
233 *out_len = hash_len;
234 return SC_SUCCESS;
235 }
236 }
237 return SC_ERROR_INTERNAL;
238 }
239
240 #ifdef ENABLE_OPENSSL
241
hash_flag2md(unsigned int hash)242 static const EVP_MD* hash_flag2md(unsigned int hash)
243 {
244 switch (hash & SC_ALGORITHM_RSA_HASHES) {
245 case SC_ALGORITHM_RSA_HASH_SHA1:
246 return EVP_sha1();
247 case SC_ALGORITHM_RSA_HASH_SHA224:
248 return EVP_sha224();
249 case SC_ALGORITHM_RSA_HASH_SHA256:
250 return EVP_sha256();
251 case SC_ALGORITHM_RSA_HASH_SHA384:
252 return EVP_sha384();
253 case SC_ALGORITHM_RSA_HASH_SHA512:
254 return EVP_sha512();
255 default:
256 return NULL;
257 }
258 }
259
mgf1_flag2md(unsigned int mgf1)260 static const EVP_MD* mgf1_flag2md(unsigned int mgf1)
261 {
262 switch (mgf1 & SC_ALGORITHM_MGF1_HASHES) {
263 case SC_ALGORITHM_MGF1_SHA1:
264 return EVP_sha1();
265 case SC_ALGORITHM_MGF1_SHA224:
266 return EVP_sha224();
267 case SC_ALGORITHM_MGF1_SHA256:
268 return EVP_sha256();
269 case SC_ALGORITHM_MGF1_SHA384:
270 return EVP_sha384();
271 case SC_ALGORITHM_MGF1_SHA512:
272 return EVP_sha512();
273 default:
274 return NULL;
275 }
276 }
277
278 /* add PKCS#1 v2.0 PSS padding */
sc_pkcs1_add_pss_padding(unsigned int hash,unsigned int mgf1_hash,const u8 * in,size_t in_len,u8 * out,size_t * out_len,size_t mod_bits)279 static int sc_pkcs1_add_pss_padding(unsigned int hash, unsigned int mgf1_hash,
280 const u8 *in, size_t in_len, u8 *out, size_t *out_len, size_t mod_bits)
281 {
282 /* hLen = sLen in our case */
283 int rv = SC_ERROR_INTERNAL, i, j, hlen, dblen, plen, round, mgf_rounds;
284 int mgf1_hlen;
285 const EVP_MD* md, *mgf1_md;
286 EVP_MD_CTX* ctx = NULL;
287 u8 buf[8];
288 u8 salt[EVP_MAX_MD_SIZE], mask[EVP_MAX_MD_SIZE];
289 size_t mod_length = (mod_bits + 7) / 8;
290
291 if (*out_len < mod_length)
292 return SC_ERROR_BUFFER_TOO_SMALL;
293
294 md = hash_flag2md(hash);
295 if (md == NULL)
296 return SC_ERROR_NOT_SUPPORTED;
297 hlen = EVP_MD_size(md);
298 dblen = mod_length - hlen - 1; /* emLen - hLen - 1 */
299 plen = mod_length - 2*hlen - 1;
300 if (in_len != (unsigned)hlen)
301 return SC_ERROR_INVALID_ARGUMENTS;
302 if (2 * (unsigned)hlen + 2 > mod_length)
303 /* RSA key too small for chosen hash (1296 bits or higher needed for
304 * signing SHA-512 hashes) */
305 return SC_ERROR_NOT_SUPPORTED;
306
307 if (RAND_bytes(salt, hlen) != 1)
308 return SC_ERROR_INTERNAL;
309
310 /* Hash M' to create H */
311 if (!(ctx = EVP_MD_CTX_create()))
312 goto done;
313 memset(buf, 0x00, 8);
314 if (EVP_DigestInit_ex(ctx, md, NULL) != 1 ||
315 EVP_DigestUpdate(ctx, buf, 8) != 1 ||
316 EVP_DigestUpdate(ctx, in, hlen) != 1 || /* mHash */
317 EVP_DigestUpdate(ctx, salt, hlen) != 1) {
318 goto done;
319 }
320
321 /* Construct padding2, salt, H, and BC in the output block */
322 /* DB = PS || 0x01 || salt */
323 memset(out, 0x00, plen - 1); /* emLen - sLen - hLen - 2 */
324 out[plen - 1] = 0x01;
325 memcpy(out + plen, salt, hlen);
326 if (EVP_DigestFinal_ex(ctx, out + dblen, NULL) != 1) { /* H */
327 goto done;
328 }
329 out[dblen + hlen] = 0xBC;
330 /* EM = DB* || H || 0xbc
331 * *the first part is masked later */
332
333 /* Construct the DB mask block by block and XOR it in. */
334 mgf1_md = mgf1_flag2md(mgf1_hash);
335 if (mgf1_md == NULL)
336 return SC_ERROR_NOT_SUPPORTED;
337 mgf1_hlen = EVP_MD_size(mgf1_md);
338
339 mgf_rounds = (dblen + mgf1_hlen - 1) / mgf1_hlen; /* round up */
340 for (round = 0; round < mgf_rounds; ++round) {
341 buf[0] = (round&0xFF000000U) >> 24;
342 buf[1] = (round&0x00FF0000U) >> 16;
343 buf[2] = (round&0x0000FF00U) >> 8;
344 buf[3] = (round&0x000000FFU);
345 if (EVP_DigestInit_ex(ctx, mgf1_md, NULL) != 1 ||
346 EVP_DigestUpdate(ctx, out + dblen, hlen) != 1 || /* H (Z parameter of MGF1) */
347 EVP_DigestUpdate(ctx, buf, 4) != 1 || /* C */
348 EVP_DigestFinal_ex(ctx, mask, NULL) != 1) {
349 goto done;
350 }
351 /* this is no longer part of the MGF1, but actually
352 * XORing mask with DB to create maskedDB inplace */
353 for (i = round * mgf1_hlen, j = 0; i < dblen && j < mgf1_hlen; ++i, ++j) {
354 out[i] ^= mask[j];
355 }
356 }
357
358 /* Set leftmost N bits in leftmost octet in maskedDB to zero
359 * to make sure the result is smaller than the modulus ( +1)
360 */
361 out[0] &= (0xff >> (8 * mod_length - mod_bits + 1));
362
363 *out_len = mod_length;
364 rv = SC_SUCCESS;
365
366 done:
367 OPENSSL_cleanse(salt, sizeof(salt));
368 OPENSSL_cleanse(mask, sizeof(mask));
369 if (ctx) {
370 EVP_MD_CTX_destroy(ctx);
371 }
372 return rv;
373 }
374
hash_len2algo(size_t hash_len)375 static int hash_len2algo(size_t hash_len)
376 {
377 switch (hash_len) {
378 case SHA_DIGEST_LENGTH:
379 return SC_ALGORITHM_RSA_HASH_SHA1;
380 case SHA224_DIGEST_LENGTH:
381 return SC_ALGORITHM_RSA_HASH_SHA224;
382 case SHA256_DIGEST_LENGTH:
383 return SC_ALGORITHM_RSA_HASH_SHA256;
384 case SHA384_DIGEST_LENGTH:
385 return SC_ALGORITHM_RSA_HASH_SHA384;
386 case SHA512_DIGEST_LENGTH:
387 return SC_ALGORITHM_RSA_HASH_SHA512;
388 }
389 /* Should never happen -- the mechanism and data should be already
390 * verified to match one of the above. If not, we will fail later
391 */
392 return SC_ALGORITHM_RSA_HASH_NONE;
393 }
394 #endif
395
396 /* general PKCS#1 encoding function */
sc_pkcs1_encode(sc_context_t * ctx,unsigned long flags,const u8 * in,size_t in_len,u8 * out,size_t * out_len,size_t mod_bits)397 int sc_pkcs1_encode(sc_context_t *ctx, unsigned long flags,
398 const u8 *in, size_t in_len, u8 *out, size_t *out_len, size_t mod_bits)
399 {
400 int rv, i;
401 size_t tmp_len = *out_len;
402 const u8 *tmp = in;
403 unsigned int hash_algo, pad_algo;
404 size_t mod_len = (mod_bits + 7) / 8;
405 #ifdef ENABLE_OPENSSL
406 unsigned int mgf1_hash;
407 #endif
408
409 LOG_FUNC_CALLED(ctx);
410
411 hash_algo = flags & SC_ALGORITHM_RSA_HASHES;
412 pad_algo = flags & SC_ALGORITHM_RSA_PADS;
413 if (pad_algo == 0)
414 pad_algo = SC_ALGORITHM_RSA_PAD_NONE;
415 sc_log(ctx, "hash algorithm 0x%X, pad algorithm 0x%X", hash_algo, pad_algo);
416
417 if ((pad_algo == SC_ALGORITHM_RSA_PAD_PKCS1 || pad_algo == SC_ALGORITHM_RSA_PAD_NONE) &&
418 hash_algo != SC_ALGORITHM_RSA_HASH_NONE) {
419 i = sc_pkcs1_add_digest_info_prefix(hash_algo, in, in_len, out, &tmp_len);
420 if (i != SC_SUCCESS) {
421 sc_log(ctx, "Unable to add digest info 0x%x", hash_algo);
422 LOG_FUNC_RETURN(ctx, i);
423 }
424 tmp = out;
425 } else {
426 tmp_len = in_len;
427 }
428
429 switch(pad_algo) {
430 case SC_ALGORITHM_RSA_PAD_NONE:
431 /* padding done by card => nothing to do */
432 if (out != tmp)
433 memcpy(out, tmp, tmp_len);
434 *out_len = tmp_len;
435 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
436 case SC_ALGORITHM_RSA_PAD_PKCS1:
437 /* add pkcs1 bt01 padding */
438 rv = sc_pkcs1_add_01_padding(tmp, tmp_len, out, out_len, mod_len);
439 LOG_FUNC_RETURN(ctx, rv);
440 case SC_ALGORITHM_RSA_PAD_PSS:
441 /* add PSS padding */
442 #ifdef ENABLE_OPENSSL
443 mgf1_hash = flags & SC_ALGORITHM_MGF1_HASHES;
444 if (hash_algo == SC_ALGORITHM_RSA_HASH_NONE) {
445 /* this is generic RSA_PKCS1_PSS mechanism with hash
446 * already done outside of the module. The parameters
447 * were already checked so we need to adjust the hash
448 * algorithm to do the padding with the correct hash
449 * function.
450 */
451 hash_algo = hash_len2algo(tmp_len);
452 }
453 rv = sc_pkcs1_add_pss_padding(hash_algo, mgf1_hash,
454 tmp, tmp_len, out, out_len, mod_bits);
455 #else
456 rv = SC_ERROR_NOT_SUPPORTED;
457 #endif
458 LOG_FUNC_RETURN(ctx, rv);
459 default:
460 /* We shouldn't be called with an unexpected padding type, we've already
461 * returned SC_ERROR_NOT_SUPPORTED if the card can't be used. */
462 LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL);
463 }
464 }
465
sc_get_encoding_flags(sc_context_t * ctx,unsigned long iflags,unsigned long caps,unsigned long * pflags,unsigned long * sflags)466 int sc_get_encoding_flags(sc_context_t *ctx,
467 unsigned long iflags, unsigned long caps,
468 unsigned long *pflags, unsigned long *sflags)
469 {
470 LOG_FUNC_CALLED(ctx);
471 if (pflags == NULL || sflags == NULL)
472 LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
473
474 sc_log(ctx, "iFlags 0x%lX, card capabilities 0x%lX", iflags, caps);
475
476 /* For ECDSA and GOSTR, we don't do any padding or hashing ourselves, the
477 * card has to support the requested operation. Similarly, for RSA with
478 * raw padding (raw RSA) and ISO9796, we require the card to do it for us.
479 * Finally, for PKCS1 (v1.5 and PSS) and ASNI X9.31 we can apply the padding
480 * ourselves if the card supports raw RSA. */
481
482 /* TODO: Could convert GOSTR3410_HASH_GOSTR3411 -> GOSTR3410_RAW and
483 * ECDSA_HASH_ -> ECDSA_RAW using OpenSSL (not much benefit though). */
484
485 if ((caps & iflags) == iflags) {
486 /* Card supports the signature operation we want to do, great, let's
487 * go with it then. */
488 *sflags = iflags;
489 *pflags = 0;
490
491 } else if ((caps & SC_ALGORITHM_RSA_PAD_PSS) &&
492 (iflags & SC_ALGORITHM_RSA_PAD_PSS)) {
493 *sflags |= SC_ALGORITHM_RSA_PAD_PSS;
494 *sflags |= iflags & SC_ALGORITHM_MGF1_HASHES;
495 *pflags = iflags & ~(iflags & (SC_ALGORITHM_MGF1_HASHES | SC_ALGORITHM_RSA_PAD_PSS));
496
497 } else if ((caps & SC_ALGORITHM_RSA_RAW) &&
498 (iflags & SC_ALGORITHM_RSA_PAD_PKCS1
499 || iflags & SC_ALGORITHM_RSA_PAD_PSS
500 || iflags & SC_ALGORITHM_RSA_PAD_NONE)) {
501 /* Use the card's raw RSA capability on the padded input */
502 *sflags = SC_ALGORITHM_RSA_PAD_NONE;
503 *pflags = iflags;
504 /* TODO emulate the OAEP decryption */
505
506 } else if ((caps & (SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE)) &&
507 (iflags & SC_ALGORITHM_RSA_PAD_PKCS1)) {
508 /* A corner case - the card can partially do PKCS1, if we prepend the
509 * DigestInfo bit it will do the rest. */
510 *sflags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE;
511 *pflags = iflags & SC_ALGORITHM_RSA_HASHES;
512
513 } else if ((iflags & SC_ALGORITHM_AES) == SC_ALGORITHM_AES) { /* TODO: seems like this constant does not belong to the same set of flags used form asymmetric algos. Fix this! */
514 *sflags = 0;
515 *pflags = 0;
516
517 } else if ((iflags & SC_ALGORITHM_AES_FLAGS) > 0) {
518 *sflags = iflags & SC_ALGORITHM_AES_FLAGS;
519 if (iflags & SC_ALGORITHM_AES_CBC_PAD)
520 *pflags = SC_ALGORITHM_AES_CBC_PAD;
521 else
522 *pflags = 0;
523
524 } else {
525 LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "unsupported algorithm");
526 }
527
528 sc_log(ctx, "pad flags 0x%lX, secure algorithm flags 0x%lX", *pflags, *sflags);
529 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
530 }
531