2 * Copyright (c) 2007-2009,2012-2014 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
25 #include <CoreFoundation/CoreFoundation.h>
26 #include <Security/SecCertificate.h>
27 #include <Security/SecCertificateInternal.h>
28 #include <Security/SecKey.h>
29 #include <Security/SecKeyPriv.h>
30 #include <Security/SecItem.h>
31 #include <Security/SecAsn1Types.h>
32 #include <Security/oidsalg.h>
33 #include <Security/SecureTransport.h>
34 #include <Security/SecRandom.h>
35 #include <utilities/array_size.h>
36 #include <utilities/SecCFWrappers.h>
37 #include <CommonCrypto/CommonDigest.h>
38 #include <libDER/libDER.h>
41 #include <corecrypto/ccsha1.h>
42 #include <corecrypto/ccsha2.h>
44 #include "Security_regressions.h"
46 #include "utilities/SecCFRelease.h"
48 static void testdigestandsignalg(SecKeyRef privKey
, SecKeyRef pubKey
, const SecAsn1AlgId
*algId
) {
49 uint8_t dataToDigest
[256] = {0,};
50 size_t dataToDigestLen
= sizeof(dataToDigest
);
51 size_t sigLen
= SecKeyGetSize(privKey
, kSecKeySignatureSize
);
55 oid
.length
= algId
->algorithm
.Length
;
56 oid
.data
= algId
->algorithm
.Data
;
58 /* Get the oid in decimal for display purposes. */
59 CFStringRef oidStr
= SecDERItemCopyOIDDecimalRepresentation(kCFAllocatorDefault
, &oid
);
61 CFStringGetCString(oidStr
, oidBuf
, sizeof(oidBuf
), kCFStringEncodingUTF8
);
68 ok_status(status
= SecKeyDigestAndSign(privKey
, algId
, dataToDigest
, dataToDigestLen
,
69 sig
, &sigLen
), "digest and sign %s with %ld bit RSA key", oidBuf
, sigLen
* 8);
71 skip("SecKeyDigestAndSign failed", 3, status
== errSecSuccess
);
73 /* Verify the signature we just made. */
74 ok_status(SecKeyDigestAndVerify(pubKey
, algId
, dataToDigest
, dataToDigestLen
,
75 sig
, sigLen
), "digest and verify");
76 /* Invalidate the signature. */
78 is_status(SecKeyDigestAndVerify(pubKey
, algId
, dataToDigest
, dataToDigestLen
,
79 sig
, sigLen
), errSSLCrypto
, "digest and verify bad sig");
81 dataToDigest
[0] ^= 0xff;
82 is_status(SecKeyDigestAndVerify(pubKey
, algId
, dataToDigest
, dataToDigestLen
,
83 sig
, sigLen
), errSSLCrypto
, "digest and verify bad digest");
87 static void testdigestandsign(SecKeyRef privKey
, SecKeyRef pubKey
) {
88 static const SecAsn1Oid
*oids
[] = {
90 &CSSMOID_SHA224WithRSA
,
91 &CSSMOID_SHA256WithRSA
,
92 &CSSMOID_SHA384WithRSA
,
93 &CSSMOID_SHA512WithRSA
,
95 &CSSMOID_SHA1WithRSA_OIW
,
96 &CSSMOID_SHA1WithDSA
, // BSAFE
97 &CSSMOID_SHA1WithDSA_CMS
, // X509/CMS
98 &CSSMOID_SHA1WithDSA_JDK
, // JDK 1.1
104 SecAsn1AlgId algId
= {};
105 for (ix
= 0; ix
< array_size(oids
); ++ix
) {
107 algId
.algorithm
= *oids
[ix
];
109 algId
.algorithm
.Length
= 0;
110 algId
.algorithm
.Data
= NULL
;
113 testdigestandsignalg(privKey
, pubKey
, &algId
);
118 static void dump_bytes(uint8_t* bytes
, size_t amount
)
121 printf("0x%02x ", *bytes
);
128 #define kEncryptDecryptTestCount 6
129 static void test_encrypt_decrypt(SecKeyRef pubKey
, SecKeyRef privKey
, uint32_t padding
, size_t keySizeInBytes
)
132 size_t max_len
= keySizeInBytes
;
134 case kSecPaddingNone
: max_len
= keySizeInBytes
; break;
135 case kSecPaddingOAEP
: max_len
= keySizeInBytes
- 2 - 2 * CC_SHA1_DIGEST_LENGTH
; break;
136 case kSecPaddingPKCS1
: max_len
= keySizeInBytes
- 11; break;
137 default: skip("what is the max_len for this padding?", 5, false);
140 uint8_t secret
[max_len
+ 2], encrypted_secret
[keySizeInBytes
], decrypted_secret
[keySizeInBytes
];
141 uint8_t *secret_ptr
= secret
;
142 size_t secret_len
= max_len
;
143 size_t encrypted_secret_len
= sizeof(encrypted_secret
);
144 size_t decrypted_secret_len
= sizeof(decrypted_secret
);
145 memset(decrypted_secret
, 0xff, decrypted_secret_len
);
146 ok_status(SecRandomCopyBytes(kSecRandomDefault
, sizeof(secret
), secret
),"rng");
148 // zero pad, no accidental second zero byte
149 if (padding
== kSecPaddingNone
) {
154 is_status(SecKeyEncrypt(pubKey
, padding
,
155 secret
, sizeof(secret
),
156 encrypted_secret
, &encrypted_secret_len
), errSecParam
, "encrypt secret (overflow)");
157 ok_status(SecKeyEncrypt(pubKey
, padding
,
159 encrypted_secret
, &encrypted_secret_len
), "encrypt secret");
161 ok_status(SecKeyDecrypt(privKey
, padding
,
162 encrypted_secret
, encrypted_secret_len
,
163 decrypted_secret
, &decrypted_secret_len
), "decrypt secret");
165 // zero padding is removed on decode
166 if (padding
== kSecPaddingNone
) {
171 ok(decrypted_secret_len
== secret_len
, "correct length");
172 ok_status(memcmp(secret_ptr
, decrypted_secret
, secret_len
), "verify secret");
176 #define kKeyGenTestCount (50 + (3*kEncryptDecryptTestCount))
177 static void testkeygen(size_t keySizeInBits
) {
178 SecKeyRef pubKey
= NULL
, privKey
= NULL
;
179 size_t keySizeInBytes
= (keySizeInBits
+ 7) / 8;
182 int32_t iKeySizeInBits
= (int32_t) keySizeInBits
;
183 kzib
= CFNumberCreate(NULL
, kCFNumberSInt32Type
, &iKeySizeInBits
);
184 CFMutableDictionaryRef kgp
= CFDictionaryCreateMutable(NULL
, 0, NULL
, NULL
);
185 CFDictionaryAddValue(kgp
, kSecAttrKeyType
, kSecAttrKeyTypeRSA
);
186 CFDictionaryAddValue(kgp
, kSecAttrKeySizeInBits
, kzib
);
189 ok_status(status
= SecKeyGeneratePair(kgp
, &pubKey
, &privKey
),
190 "Generate %ld bit (%ld byte) RSA keypair", keySizeInBits
,
196 skip("keygen failed", 8, status
== errSecSuccess
);
197 ok(pubKey
, "pubkey returned");
198 ok(privKey
, "privKey returned");
199 is(SecKeyGetSize(pubKey
, kSecKeyKeySizeInBits
), (size_t) keySizeInBits
, "public key size is ok");
200 is(SecKeyGetSize(privKey
, kSecKeyKeySizeInBits
), (size_t) keySizeInBits
, "private key size is ok");
202 /* Sign something. */
203 uint8_t something
[keySizeInBytes
];
204 size_t something_len
= keySizeInBytes
- 11;
205 ok_status(SecRandomCopyBytes(kSecRandomDefault
, sizeof(something
), something
),"rng");
206 uint8_t sig
[keySizeInBytes
];
207 size_t sigLen
= sizeof(sig
);
208 if (privKey
!= NULL
&& pubKey
!= NULL
) {
209 is_status(SecKeyRawSign(privKey
, kSecPaddingPKCS1
,
210 something
, something_len
+ 1, sig
, &sigLen
),
211 errSecParam
, "sign overflow");
212 ok_status(SecKeyRawSign(privKey
, kSecPaddingPKCS1
,
213 something
, something_len
, sig
, &sigLen
), "sign something");
214 ok_status(SecKeyRawVerify(pubKey
, kSecPaddingPKCS1
,
215 something
, something_len
, sig
, sigLen
), "verify sig on something");
217 // Torture test ASN.1 encoder by setting high bit to 1.
218 uint8_t digest
[CC_SHA512_DIGEST_LENGTH
] = {
219 0x80, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
220 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
221 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
222 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
223 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
224 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
225 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
226 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
228 //CC_MD2(something, sizeof(something), digest);
229 ok_status(!SecKeyRawSign(privKey
, kSecPaddingPKCS1MD2
,
230 digest
, CC_MD2_DIGEST_LENGTH
, sig
, &sigLen
),
231 "don't sign md2 digest");
232 ok_status(!SecKeyRawVerify(pubKey
, kSecPaddingPKCS1MD2
,
233 digest
, CC_MD2_DIGEST_LENGTH
, sig
, sigLen
),
234 "verify sig on md2 digest fails");
236 //CC_MD5(something, sizeof(something), digest);
237 sigLen
= sizeof(sig
);
238 ok_status(!SecKeyRawSign(privKey
, kSecPaddingPKCS1MD5
,
239 digest
, CC_MD5_DIGEST_LENGTH
, sig
, &sigLen
),
240 "don't sign md5 digest");
241 ok_status(!SecKeyRawVerify(pubKey
, kSecPaddingPKCS1MD5
,
242 digest
, CC_MD5_DIGEST_LENGTH
, sig
, sigLen
),
243 "verify sig on md5 digest fails");
245 //CCDigest(kCCDigestSHA1, something, sizeof(something), digest);
246 sigLen
= sizeof(sig
);
247 ok_status(SecKeyRawSign(privKey
, kSecPaddingPKCS1SHA1
,
248 digest
, CC_SHA1_DIGEST_LENGTH
, sig
, &sigLen
),
250 ok_status(SecKeyRawVerify(pubKey
, kSecPaddingPKCS1SHA1
,
251 digest
, CC_SHA1_DIGEST_LENGTH
, sig
, sigLen
),
252 "verify sig on sha1 digest");
254 uint8_t signature
[keySizeInBytes
], *ptr
= signature
;
255 size_t signature_len
= sizeof(signature
);
256 ok_status(SecKeyDecrypt(pubKey
, kSecPaddingNone
, sig
, sigLen
, signature
, &signature_len
), "inspect signature");
257 is(signature_len
, keySizeInBytes
- 1, "got signature");
258 while(*ptr
&& ((size_t)(ptr
- signature
) < signature_len
)) ptr
++;
259 is(signature
+ signature_len
- ptr
, 16 /* length(\0 || OID_SHA1) */ + CC_SHA1_DIGEST_LENGTH
, "successful decode");
261 /* PKCS1 padding is 00 01 PAD * 8 or more 00 data.
262 data is SEQ { SEQ { OID NULL } BIT STRING 00 DIGEST }
263 So min data + pad overhead is 11 + 9 + oidlen
264 oidlen = 11 for the sha2 family of oids, so we have 29 bytes; or
265 232 bits of minimum overhead. */
266 const size_t pkcs1Overhead
= 232;
267 if (keySizeInBits
> 224 + pkcs1Overhead
) {
268 //CC_SHA224(something, sizeof(something), digest);
269 sigLen
= sizeof(sig
);
270 ok_status(SecKeyRawSign(privKey
, kSecPaddingPKCS1SHA224
,
271 digest
, CC_SHA224_DIGEST_LENGTH
, sig
, &sigLen
),
272 "sign sha224 digest");
273 ok_status(SecKeyRawVerify(pubKey
, kSecPaddingPKCS1SHA224
,
274 digest
, CC_SHA224_DIGEST_LENGTH
, sig
, sigLen
),
275 "verify sig on sha224 digest");
278 if (keySizeInBits
> 256 + pkcs1Overhead
) {
279 //CC_SHA256(something, sizeof(something), digest);
280 sigLen
= sizeof(sig
);
281 ok_status(SecKeyRawSign(privKey
, kSecPaddingPKCS1SHA256
,
282 digest
, CC_SHA256_DIGEST_LENGTH
, sig
, &sigLen
),
283 "sign sha256 digest");
284 ok_status(SecKeyRawVerify(pubKey
, kSecPaddingPKCS1SHA256
,
285 digest
, CC_SHA256_DIGEST_LENGTH
, sig
, sigLen
),
286 "verify sig on sha256 digest");
289 if (keySizeInBits
> 384 + pkcs1Overhead
) {
290 //CC_SHA384(something, sizeof(something), digest);
291 sigLen
= sizeof(sig
);
292 ok_status(SecKeyRawSign(privKey
, kSecPaddingPKCS1SHA384
,
293 digest
, CC_SHA384_DIGEST_LENGTH
, sig
, &sigLen
),
294 "sign sha384 digest");
295 ok_status(SecKeyRawVerify(pubKey
, kSecPaddingPKCS1SHA384
,
296 digest
, CC_SHA384_DIGEST_LENGTH
, sig
, sigLen
),
297 "verify sig on sha384 digest");
300 if (keySizeInBits
> 512 + pkcs1Overhead
) {
301 //CC_SHA512(something, sizeof(something), digest);
302 sigLen
= sizeof(sig
);
303 ok_status(SecKeyRawSign(privKey
, kSecPaddingPKCS1SHA512
,
304 digest
, CC_SHA512_DIGEST_LENGTH
, sig
, &sigLen
),
305 "sign sha512 digest");
306 ok_status(SecKeyRawVerify(pubKey
, kSecPaddingPKCS1SHA512
,
307 digest
, CC_SHA512_DIGEST_LENGTH
, sig
, sigLen
),
308 "verify sig on sha512 digest");
312 test_encrypt_decrypt(pubKey
, privKey
, kSecPaddingNone
, keySizeInBytes
);
313 test_encrypt_decrypt(pubKey
, privKey
, kSecPaddingPKCS1
, keySizeInBytes
);
314 test_encrypt_decrypt(pubKey
, privKey
, kSecPaddingOAEP
, keySizeInBytes
);
316 testdigestandsign(privKey
, pubKey
);
318 const void *privkeys
[] = {
321 const void *privvalues
[] = {
324 CFDictionaryRef privitem
= CFDictionaryCreate(NULL
, privkeys
, privvalues
,
325 array_size(privkeys
), NULL
, NULL
);
326 ok_status(SecItemAdd(privitem
, NULL
), "add private key");
327 ok_status(SecItemDelete(privitem
), "delete private key");
328 CFReleaseNull(privitem
);
330 const void *pubkeys
[] = {
333 const void *pubvalues
[] = {
336 CFDictionaryRef pubitem
= CFDictionaryCreate(NULL
, pubkeys
, pubvalues
,
337 array_size(pubkeys
), NULL
, NULL
);
338 ok_status(SecItemAdd(pubitem
, NULL
), "add public key");
339 ok_status(SecItemDelete(pubitem
), "delete public key");
340 CFReleaseNull(pubitem
);
343 CFReleaseNull(pubKey
);
344 CFReleaseNull(privKey
);
348 #define kKeyGen2TestCount 12
349 static void testkeygen2(size_t keySizeInBits
) {
350 SecKeyRef pubKey
= NULL
, privKey
= NULL
;
351 size_t keySizeInBytes
= (keySizeInBits
+ 7) / 8;
354 CFUUIDRef ourUUID
= CFUUIDCreate(kCFAllocatorDefault
);
355 CFStringRef uuidString
= CFUUIDCreateString(kCFAllocatorDefault
, ourUUID
);
356 CFMutableStringRef publicName
= CFStringCreateMutableCopy(kCFAllocatorDefault
, 0, uuidString
);
357 CFMutableStringRef privateName
= CFStringCreateMutableCopy(kCFAllocatorDefault
, 0, uuidString
);
359 CFReleaseNull(ourUUID
);
360 CFReleaseNull(uuidString
);
362 CFStringAppend(publicName
, CFSTR("-Public-40"));
363 CFStringAppend(privateName
, CFSTR("-Private-40"));
364 CFMutableDictionaryRef pubd
= CFDictionaryCreateMutable(NULL
, 0, NULL
, NULL
);
365 CFMutableDictionaryRef privd
= CFDictionaryCreateMutable(NULL
, 0, NULL
, NULL
);
367 CFDictionaryAddValue(pubd
, kSecAttrLabel
, publicName
);
368 CFDictionaryAddValue(privd
, kSecAttrLabel
, privateName
);
370 int32_t iKeySizeInBits
= (int32_t) keySizeInBits
;
371 kzib
= CFNumberCreate(NULL
, kCFNumberSInt32Type
, &iKeySizeInBits
);
372 CFMutableDictionaryRef kgp
= CFDictionaryCreateMutable(NULL
, 0, NULL
, NULL
);
373 CFDictionaryAddValue(kgp
, kSecAttrKeyType
, kSecAttrKeyTypeRSA
);
374 CFDictionaryAddValue(kgp
, kSecAttrKeySizeInBits
, kzib
);
375 CFDictionaryAddValue(kgp
, kSecAttrIsPermanent
, kCFBooleanTrue
);
376 CFDictionaryAddValue(kgp
, kSecPublicKeyAttrs
, pubd
);
377 CFDictionaryAddValue(kgp
, kSecPrivateKeyAttrs
, privd
);
380 ok_status(status
= SecKeyGeneratePair(kgp
, &pubKey
, &privKey
),
381 "Generate %ld bit (%ld byte) persistent RSA keypair",
382 keySizeInBits
, keySizeInBytes
);
387 skip("keygen failed", 8, status
== errSecSuccess
);
388 ok(pubKey
, "pubkey returned");
389 ok(privKey
, "privKey returned");
390 is(SecKeyGetSize(pubKey
, kSecKeyKeySizeInBits
), (size_t) keySizeInBits
, "public key size is ok");
391 is(SecKeyGetSize(privKey
, kSecKeyKeySizeInBits
), (size_t) keySizeInBits
, "private key size is ok");
393 SecKeyRef pubKey2
, privKey2
;
394 CFDictionaryAddValue(pubd
, kSecClass
, kSecClassKey
);
395 CFDictionaryAddValue(pubd
, kSecReturnRef
, kCFBooleanTrue
);
396 CFDictionaryAddValue(privd
, kSecClass
, kSecClassKey
);
397 CFDictionaryAddValue(privd
, kSecReturnRef
, kCFBooleanTrue
);
398 CFDictionaryAddValue(privd
, kSecAttrCanSign
, kCFBooleanTrue
);
399 ok_status(SecItemCopyMatching(pubd
, (CFTypeRef
*)&pubKey2
),
400 "retrieve pub key by label");
401 ok_status(SecItemCopyMatching(privd
, (CFTypeRef
*)&privKey2
),
402 "retrieve priv key by label and kSecAttrCanSign");
404 /* Sign something. */
405 uint8_t something
[50] = {0x80, 0xbe, 0xef, 0xba, 0xd0, };
406 uint8_t sig
[keySizeInBytes
];
407 size_t sigLen
= keySizeInBytes
;
408 ok_status(SecKeyRawSign(privKey2
, kSecPaddingPKCS1
,
409 something
, sizeof(something
), sig
, &sigLen
), "sign something");
410 ok_status(SecKeyRawVerify(pubKey2
, kSecPaddingPKCS1
,
411 something
, sizeof(something
), sig
, sigLen
), "verify sig on something");
413 sigLen
= keySizeInBytes
;
414 is_status(SecKeyEncrypt(pubKey2
, kSecPaddingPKCS1SHA1
,
415 something
, sizeof(something
), sig
, &sigLen
), errSecParam
,
416 "encrypt something with invalid padding");
419 CFReleaseNull(pubKey2
);
420 CFReleaseNull(privKey2
);
422 /* delete from keychain - note: do it before releasing publicName and privateName
423 because pubd and privd have no retain/release callbacks */
424 ok_status(SecItemDelete(pubd
), "delete generated pub key");
425 ok_status(SecItemDelete(privd
), "delete generated priv key");
429 CFReleaseNull(pubKey
);
430 CFReleaseNull(privKey
);
432 CFReleaseNull(publicName
);
433 CFReleaseNull(privateName
);
439 static const int kTestSupportedCount
= 3 + (4 * 11) + 2 + (4 * 5);
440 static void testsupportedalgos(size_t keySizeInBits
)
442 SecKeyRef pubKey
= NULL
, privKey
= NULL
;
443 size_t keySizeInBytes
= (keySizeInBits
+ 7) / 8;
446 int32_t iKeySizeInBits
= (int32_t) keySizeInBits
;
447 kzib
= CFNumberCreate(NULL
, kCFNumberSInt32Type
, &iKeySizeInBits
);
448 CFMutableDictionaryRef kgp
= CFDictionaryCreateMutable(NULL
, 0, NULL
, NULL
);
449 CFDictionaryAddValue(kgp
, kSecAttrKeyType
, kSecAttrKeyTypeRSA
);
450 CFDictionaryAddValue(kgp
, kSecAttrKeySizeInBits
, kzib
);
453 ok_status(status
= SecKeyGeneratePair(kgp
, &pubKey
, &privKey
),
454 "Generate %ld bit (%ld byte) persistent RSA keypair",
455 keySizeInBits
, keySizeInBytes
);
459 is(SecKeyGetSize(pubKey
, kSecKeyKeySizeInBits
), (size_t) keySizeInBits
, "public key size is ok");
460 is(SecKeyGetSize(privKey
, kSecKeyKeySizeInBits
), (size_t) keySizeInBits
, "private key size is ok");
462 const SecKeyAlgorithm sign
[] = {
463 kSecKeyAlgorithmRSASignatureRaw
,
464 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1
,
465 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1
,
466 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA224
,
467 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA224
,
468 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256
,
469 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256
,
470 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384
,
471 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA384
,
472 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512
,
473 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512
,
476 for (size_t i
= 0; i
< array_size(sign
); i
++) {
477 ok(SecKeyIsAlgorithmSupported(privKey
, kSecKeyOperationTypeSign
, sign
[i
]),
478 "privKey supports sign algorithm %@", sign
[i
]);
479 ok(SecKeyIsAlgorithmSupported(pubKey
, kSecKeyOperationTypeVerify
, sign
[i
]),
480 "pubKey supports verify algorithm %@", sign
[i
]);
481 // Our privKey actually supports even verify operation because it is adapter over decrypt...
482 ok(SecKeyIsAlgorithmSupported(privKey
, kSecKeyOperationTypeVerify
, sign
[i
]),
483 "privKey supports verify algorithm %@", sign
[i
]);
484 ok(!SecKeyIsAlgorithmSupported(pubKey
, kSecKeyOperationTypeSign
, sign
[i
]),
485 "pubKey doesn't support verify algorithm %@", sign
[i
]);
487 ok(!SecKeyIsAlgorithmSupported(privKey
, kSecKeyOperationTypeSign
, kSecKeyAlgorithmECDSASignatureDigestX962
),
488 "RSA privKey does not support ECDSA algorithm");
489 ok(!SecKeyIsAlgorithmSupported(privKey
, kSecKeyOperationTypeVerify
, kSecKeyAlgorithmECDSASignatureDigestX962
),
490 "RSA pubKey does not support ECDSA algorithm");
492 const SecKeyAlgorithm crypt
[] = {
493 kSecKeyAlgorithmRSAEncryptionRaw
,
494 kSecKeyAlgorithmRSAEncryptionPKCS1
,
495 kSecKeyAlgorithmRSAEncryptionOAEPSHA1
,
496 kSecKeyAlgorithmRSAEncryptionOAEPSHA224
,
497 kSecKeyAlgorithmRSAEncryptionOAEPSHA256
,
498 // kSecKeyAlgorithmRSAEncryptionOAEPSHA384,
499 // kSecKeyAlgorithmRSAEncryptionOAEPSHA512,
501 for (size_t i
= 0; i
< array_size(crypt
); i
++) {
502 ok(SecKeyIsAlgorithmSupported(privKey
, kSecKeyOperationTypeDecrypt
, crypt
[i
]),
503 "privKey supports decrypt algorithm %@", crypt
[i
]);
504 ok(SecKeyIsAlgorithmSupported(pubKey
, kSecKeyOperationTypeEncrypt
, crypt
[i
]),
505 "pubKey supports encrypt algorithm %@", crypt
[i
]);
506 ok(!SecKeyIsAlgorithmSupported(privKey
, kSecKeyOperationTypeEncrypt
, crypt
[i
]),
507 "privKey doesn't supports encrypt algorithm %@", crypt
[i
]);
508 ok(SecKeyIsAlgorithmSupported(pubKey
, kSecKeyOperationTypeDecrypt
, crypt
[i
]),
509 "pubKey supports decrypt algorithm %@", crypt
[i
]);
513 CFReleaseNull(pubKey
);
514 CFReleaseNull(privKey
);
517 #define kCreateWithDataTestCount 13
518 static void testcreatewithdata(unsigned long keySizeInBits
)
520 size_t keySizeInBytes
= (keySizeInBits
+ 7) / 8;
521 int32_t keysz32
= (int32_t)keySizeInBits
;
523 CFNumberRef kzib
= CFNumberCreate(NULL
, kCFNumberSInt32Type
, &keysz32
);
524 CFDictionaryRef kgp
= CFDictionaryCreateForCFTypes(kCFAllocatorDefault
,
525 kSecAttrKeyType
, kSecAttrKeyTypeRSA
,
526 kSecAttrKeySizeInBits
, kzib
,
527 kSecAttrIsPermanent
, kCFBooleanFalse
,
529 SecKeyRef pubKey
= NULL
, privKey
= NULL
;
531 ok_status(status
= SecKeyGeneratePair(kgp
, &pubKey
, &privKey
),
532 "Generate %ld bit (%ld byte) RSA keypair (status = %d)",
533 keySizeInBits
, keySizeInBytes
, (int)status
);
536 CFMutableDictionaryRef kcwd
= CFDictionaryCreateMutableForCFTypesWith(kCFAllocatorDefault
,
537 kSecAttrKeyType
, kSecAttrKeyTypeRSA
,
538 kSecAttrKeySizeInBits
, kzib
,
539 kSecAttrIsPermanent
, kCFBooleanFalse
,
543 CFErrorRef error
= NULL
;
544 CFDataRef privExternalData
= NULL
, pubExternalData
= NULL
;
545 SecKeyRef dataKey
= NULL
;
548 privExternalData
= SecKeyCopyExternalRepresentation(privKey
, &error
);
549 ok(privExternalData
&& CFGetTypeID(privExternalData
) == CFDataGetTypeID(),
550 "priv key SecKeyCopyExternalRepresentation failed");
551 CFReleaseNull(error
);
554 skip("invalid priv key external data", 4, privExternalData
);
556 CFDictionarySetValue(kcwd
, kSecAttrKeyClass
, kSecAttrKeyClassPrivate
);
557 dataKey
= SecKeyCreateWithData(privExternalData
, kcwd
, &error
);
558 ok(dataKey
, "priv key SecKeyCreateWithData failed");
559 CFReleaseNull(error
);
561 eq_cf(privKey
, dataKey
, "priv keys differ");
562 CFReleaseNull(dataKey
);
564 CFDictionarySetValue(kcwd
, kSecAttrKeyClass
, kSecAttrKeyClassPublic
);
565 dataKey
= SecKeyCreateWithData(privExternalData
, kcwd
, &error
);
566 ok(!dataKey
, "priv key SecKeyCreateWithData succeeded with invalid kSecAttrKeyClass");
567 CFReleaseNull(error
);
568 CFReleaseNull(dataKey
);
570 CFMutableDataRef modifiedExternalData
= CFDataCreateMutable(kCFAllocatorDefault
, 0);
571 CFDataAppend(modifiedExternalData
, privExternalData
);
572 *CFDataGetMutableBytePtr(modifiedExternalData
) ^= 0xff;
574 CFDictionarySetValue(kcwd
, kSecAttrKeyClass
, kSecAttrKeyClassPrivate
);
575 dataKey
= SecKeyCreateWithData(modifiedExternalData
, kcwd
, &error
);
576 ok(!dataKey
, "priv key SecKeyCreateWithData succeeded with invalid external data");
577 CFReleaseNull(error
);
578 CFReleaseNull(dataKey
);
580 CFReleaseNull(modifiedExternalData
);
585 pubExternalData
= SecKeyCopyExternalRepresentation(pubKey
, &error
);
586 ok(pubExternalData
&& CFGetTypeID(pubExternalData
) == CFDataGetTypeID(),
587 "pub key SecKeyCopyExternalRepresentation failed");
588 CFReleaseNull(error
);
591 skip("invalid pub key external data", 4, pubExternalData
);
593 CFDictionarySetValue(kcwd
, kSecAttrKeyClass
, kSecAttrKeyClassPublic
);
594 dataKey
= SecKeyCreateWithData(pubExternalData
, kcwd
, &error
);
595 ok(dataKey
, "pub key SecKeyCreateWithData failed");
596 CFReleaseNull(error
);
598 eq_cf(pubKey
, dataKey
, "pub keys differ");
599 CFReleaseNull(dataKey
);
601 CFDictionarySetValue(kcwd
, kSecAttrKeyClass
, kSecAttrKeyClassPrivate
);
602 dataKey
= SecKeyCreateWithData(pubExternalData
, kcwd
, &error
);
603 ok(!dataKey
, "pub key SecKeyCreateWithData succeeded with invalid kSecAttrKeyClass");
604 CFReleaseNull(error
);
605 CFReleaseNull(dataKey
);
607 CFMutableDataRef modifiedExternalData
= CFDataCreateMutable(kCFAllocatorDefault
, 0);
608 CFDataAppend(modifiedExternalData
, pubExternalData
);
609 *CFDataGetMutableBytePtr(modifiedExternalData
) ^= 0xff;
611 CFDictionarySetValue(kcwd
, kSecAttrKeyClass
, kSecAttrKeyClassPublic
);
612 dataKey
= SecKeyCreateWithData(modifiedExternalData
, kcwd
, &error
);
613 ok(!dataKey
, "pub key SecKeyCreateWithData succeeded with invalid external data");
614 CFReleaseNull(error
);
615 CFReleaseNull(dataKey
);
617 CFReleaseNull(modifiedExternalData
);
622 skip("invalid pub key external data", 1, pubExternalData
);
624 CFDictionarySetValue(kcwd
, kSecAttrKeyClass
, kSecAttrKeyClassPrivate
);
625 dataKey
= SecKeyCreateWithData(pubExternalData
, kcwd
, &error
);
626 ok(!dataKey
, "priv key SecKeyCreateWithData succeeded with public external data");
627 CFReleaseNull(error
);
628 CFReleaseNull(dataKey
);
630 CFReleaseNull(pubExternalData
);
634 skip("invalid priv key external data", 1, privExternalData
);
636 CFDictionarySetValue(kcwd
, kSecAttrKeyClass
, kSecAttrKeyClassPublic
);
637 dataKey
= SecKeyCreateWithData(privExternalData
, kcwd
, &error
);
638 ok(!dataKey
, "pub key SecKeyCreateWithData succeeded with private external data");
639 CFReleaseNull(error
);
640 CFReleaseNull(dataKey
);
642 CFReleaseNull(privExternalData
);
646 CFReleaseNull(pubKey
);
647 CFReleaseNull(privKey
);
650 #define kCopyAttributesTestCount 20
651 static void testcopyattributes(unsigned long keySizeInBits
)
653 size_t keySizeInBytes
= (keySizeInBits
+ 7) / 8;
654 int32_t keysz32
= (int32_t)keySizeInBits
;
656 CFNumberRef kzib
= CFNumberCreate(NULL
, kCFNumberSInt32Type
, &keysz32
);
657 CFDictionaryRef kgp
= CFDictionaryCreateForCFTypes(kCFAllocatorDefault
,
658 kSecAttrKeyType
, kSecAttrKeyTypeRSA
,
659 kSecAttrKeySizeInBits
, kzib
,
660 kSecAttrIsPermanent
, kCFBooleanFalse
,
662 SecKeyRef pubKey
= NULL
, privKey
= NULL
;
664 ok_status(status
= SecKeyGeneratePair(kgp
, &pubKey
, &privKey
),
665 "Generate %ld bit (%ld byte) RSA keypair (status = %d)",
666 keySizeInBits
, keySizeInBytes
, (int)status
);
669 CFDictionaryRef attributes
;
670 CFTypeRef attrValue
= NULL
, privAppLabel
= NULL
, pubAppLabel
= NULL
;
673 attributes
= SecKeyCopyAttributes(privKey
);
674 ok(attributes
&& CFGetTypeID(attributes
) == CFDictionaryGetTypeID(),
675 "priv key SecKeyCopyAttributes failed");
678 skip("invalid attributes", 8, attributes
);
680 attrValue
= CFDictionaryGetValue(attributes
, kSecAttrCanEncrypt
);
681 eq_cf(attrValue
, kCFBooleanFalse
, "invalid priv key kSecAttrCanEncrypt");
683 attrValue
= CFDictionaryGetValue(attributes
, kSecAttrCanDecrypt
);
684 eq_cf(attrValue
, kCFBooleanTrue
, "invalid priv key kSecAttrCanDecrypt");
686 attrValue
= CFDictionaryGetValue(attributes
, kSecAttrCanDerive
);
687 eq_cf(attrValue
, kCFBooleanFalse
, "invalid priv key kSecAttrCanDerive");
689 attrValue
= CFDictionaryGetValue(attributes
, kSecAttrCanSign
);
690 eq_cf(attrValue
, kCFBooleanTrue
, "invalid priv key kSecAttrCanSign");
692 attrValue
= CFDictionaryGetValue(attributes
, kSecAttrCanVerify
);
693 eq_cf(attrValue
, kCFBooleanFalse
, "invalid priv key kSecAttrCanVerify");
695 attrValue
= CFDictionaryGetValue(attributes
, kSecAttrKeyClass
);
696 eq_cf(attrValue
, kSecAttrKeyClassPrivate
, "priv key invalid kSecAttrKeyClass");
698 attrValue
= CFDictionaryGetValue(attributes
, kSecAttrKeyType
);
699 eq_cf(attrValue
, kSecAttrKeyTypeRSA
, "invalid priv key kSecAttrKeyType");
701 attrValue
= CFDictionaryGetValue(attributes
, kSecAttrKeySizeInBits
);
702 eq_cf(attrValue
, kzib
, "invalid priv key kSecAttrKeySizeInBits");
704 privAppLabel
= CFDictionaryGetValue(attributes
, kSecAttrApplicationLabel
);
705 CFRetainSafe(privAppLabel
);
707 CFReleaseNull(attributes
);
712 attributes
= SecKeyCopyAttributes(pubKey
);
713 ok(attributes
&& CFGetTypeID(attributes
) == CFDictionaryGetTypeID(),
714 "pub key SecKeyCopyAttributes failed");
717 skip("invalid attributes", 8, attributes
);
719 attrValue
= CFDictionaryGetValue(attributes
, kSecAttrCanEncrypt
);
720 eq_cf(attrValue
, kCFBooleanTrue
, "pub key invalid kSecAttrCanEncrypt");
722 // Although unusual, our RSA public key can even decrypt.
723 attrValue
= CFDictionaryGetValue(attributes
, kSecAttrCanDecrypt
);
724 eq_cf(attrValue
, kCFBooleanTrue
, "pub key invalid kSecAttrCanDecrypt");
726 attrValue
= CFDictionaryGetValue(attributes
, kSecAttrCanDerive
);
727 eq_cf(attrValue
, kCFBooleanFalse
, "pub key invalid kSecAttrCanDerive");
729 attrValue
= CFDictionaryGetValue(attributes
, kSecAttrCanSign
);
730 eq_cf(attrValue
, kCFBooleanFalse
, "pub key invalid kSecAttrCanSign");
732 attrValue
= CFDictionaryGetValue(attributes
, kSecAttrCanVerify
);
733 eq_cf(attrValue
, kCFBooleanTrue
, "pub key invalid kSecAttrCanVerify");
735 attrValue
= CFDictionaryGetValue(attributes
, kSecAttrKeyClass
);
736 eq_cf(attrValue
, kSecAttrKeyClassPublic
, "pub key invalid kSecAttrKeyClass");
738 attrValue
= CFDictionaryGetValue(attributes
, kSecAttrKeyType
);
739 eq_cf(attrValue
, kSecAttrKeyTypeRSA
, "pub key invalid kSecAttrKeyType");
741 attrValue
= CFDictionaryGetValue(attributes
, kSecAttrKeySizeInBits
);
742 eq_cf(attrValue
, kzib
, "pub key invalid kSecAttrKeySizeInBits");
744 pubAppLabel
= CFDictionaryGetValue(attributes
, kSecAttrApplicationLabel
);
745 CFRetainSafe(pubAppLabel
);
747 CFReleaseNull(attributes
);
751 eq_cf(privAppLabel
, pubAppLabel
, "priv key and pub key kSecAttrApplicationLabel differ");
753 CFReleaseNull(privAppLabel
);
754 CFReleaseNull(pubAppLabel
);
756 CFReleaseNull(pubKey
);
757 CFReleaseNull(privKey
);
760 #define kCopyPublicKeyTestCount 5
761 static void testcopypublickey(unsigned long keySizeInBits
)
763 size_t keySizeInBytes
= (keySizeInBits
+ 7) / 8;
764 int32_t keysz32
= (int32_t)keySizeInBits
;
766 CFNumberRef kzib
= CFNumberCreate(NULL
, kCFNumberSInt32Type
, &keysz32
);
767 CFDictionaryRef kgp
= CFDictionaryCreateForCFTypes(kCFAllocatorDefault
,
768 kSecAttrKeyType
, kSecAttrKeyTypeRSA
,
769 kSecAttrKeySizeInBits
, kzib
,
770 kSecAttrIsPermanent
, kCFBooleanFalse
,
774 SecKeyRef pubKey
= NULL
, privKey
= NULL
;
776 ok_status(status
= SecKeyGeneratePair(kgp
, &pubKey
, &privKey
),
777 "Generate %ld bit (%ld byte) RSA keypair (status = %d)",
778 keySizeInBits
, keySizeInBytes
, (int)status
);
781 SecKeyRef pubKeyCopy
= NULL
;
784 pubKeyCopy
= SecKeyCopyPublicKey(privKey
);
785 ok(pubKeyCopy
, "priv key SecKeyCopyPublicKey failed");
786 eq_cf(pubKeyCopy
, pubKey
, "pub key from priv key SecKeyCopyPublicKey and pub key differ");
787 CFReleaseNull(pubKeyCopy
);
791 pubKeyCopy
= SecKeyCopyPublicKey(pubKey
);
792 ok(pubKeyCopy
, "pub key SecKeyCopyPublicKey failed");
793 eq_cf(pubKeyCopy
, pubKey
, "pub key from pub key SecKeyCopyPublicKey and pub key differ");
794 CFReleaseNull(pubKeyCopy
);
797 CFReleaseNull(pubKey
);
798 CFReleaseNull(privKey
);
801 #define kSignAndVerifyTestCount 84
802 static void testsignverify(unsigned long keySizeInBits
)
804 size_t keySizeInBytes
= (keySizeInBits
+ 7) / 8;
805 int32_t keysz32
= (int32_t)keySizeInBits
;
807 CFNumberRef kzib
= CFNumberCreate(NULL
, kCFNumberSInt32Type
, &keysz32
);
808 CFDictionaryRef kgp
= CFDictionaryCreateForCFTypes(kCFAllocatorDefault
,
809 kSecAttrKeyType
, kSecAttrKeyTypeRSA
,
810 kSecAttrKeySizeInBits
, kzib
,
811 kSecAttrIsPermanent
, kCFBooleanFalse
,
815 SecKeyRef pubKey
= NULL
, privKey
= NULL
;
817 ok_status(status
= SecKeyGeneratePair(kgp
, &pubKey
, &privKey
),
818 "Generate %ld bit (%ld byte) RSA keypair (status = %d)",
819 keySizeInBits
, keySizeInBytes
, (int)status
);
822 SecKeyAlgorithm algorithms
[] = {
823 kSecKeyAlgorithmRSASignatureRaw
,
824 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1
,
825 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA224
,
826 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256
,
827 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384
,
828 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512
,
829 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1
,
830 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA224
,
831 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256
,
832 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA384
,
833 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512
,
836 CFDataRef testData
= CFStringCreateExternalRepresentation(kCFAllocatorDefault
, CFSTR("test"), kCFStringEncodingUTF8
, 0);
837 ok(testData
, "creating test data failed");
840 skip("invalid test data", 71, testData
);
842 CFErrorRef error
= NULL
;
844 for (uint32_t ix
= 0; ix
< array_size(algorithms
); ++ix
) {
845 SecKeyAlgorithm algorithm
= algorithms
[ix
];
846 SecKeyAlgorithm incompatibleAlgorithm
= (CFEqual(algorithm
, kSecKeyAlgorithmRSASignatureRaw
)) ?
847 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1
: kSecKeyAlgorithmRSASignatureRaw
;
849 CFDataRef dataToSign
= NULL
;
850 if (CFEqual(algorithm
, kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1
)) {
851 dataToSign
= CFDataCreateWithHash(kCFAllocatorDefault
, ccsha1_di(),
852 CFDataGetBytePtr(testData
), CFDataGetLength(testData
));
853 ok(dataToSign
, "creating digest failed for algorithm %@", algorithm
);
855 else if (CFEqual(algorithm
, kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA224
)) {
856 dataToSign
= CFDataCreateWithHash(kCFAllocatorDefault
, ccsha224_di(),
857 CFDataGetBytePtr(testData
), CFDataGetLength(testData
));
858 ok(dataToSign
, "creating digest failed for algorithm %@", algorithm
);
860 else if (CFEqual(algorithm
, kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256
)) {
861 dataToSign
= CFDataCreateWithHash(kCFAllocatorDefault
, ccsha256_di(),
862 CFDataGetBytePtr(testData
), CFDataGetLength(testData
));
863 ok(dataToSign
, "creating digest failed for algorithm %@", algorithm
);
865 else if (CFEqual(algorithm
, kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384
)) {
866 dataToSign
= CFDataCreateWithHash(kCFAllocatorDefault
, ccsha384_di(),
867 CFDataGetBytePtr(testData
), CFDataGetLength(testData
));
868 ok(dataToSign
, "creating digest failed for algorithm %@", algorithm
);
870 else if (CFEqual(algorithm
, kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512
)) {
871 dataToSign
= CFDataCreateWithHash(kCFAllocatorDefault
, ccsha512_di(),
872 CFDataGetBytePtr(testData
), CFDataGetLength(testData
));
873 ok(dataToSign
, "creating digest failed for algorithm %@", algorithm
);
876 CFRetainAssign(dataToSign
, testData
);
878 CFReleaseNull(error
);
881 skip("invalid data to sign", 7, dataToSign
);
883 CFDataRef signature
= SecKeyCreateSignature(pubKey
, algorithm
, dataToSign
, &error
);
884 ok(!signature
, "SecKeyCopySignature succeeded with pub key for algorithm %@", algorithm
);
885 CFReleaseNull(error
);
886 CFReleaseNull(signature
);
888 signature
= SecKeyCreateSignature(privKey
, algorithm
, dataToSign
, &error
);
889 ok(signature
, "SecKeyCopySignature failed for algorithm %@", algorithm
);
890 CFReleaseNull(error
);
893 skip("invalid signature", 4, signature
);
895 ok(!SecKeyVerifySignature(privKey
, algorithm
, dataToSign
, signature
, &error
),
896 "SecKeyVerifySignature succeeded with priv key for algorithm %@", algorithm
);
897 CFReleaseNull(error
);
899 ok(!SecKeyVerifySignature(pubKey
, incompatibleAlgorithm
, dataToSign
, signature
, &error
),
900 "SecKeyVerifySignature succeeded with wrong algorithm for algorithm %@", algorithm
);
901 CFReleaseNull(error
);
903 ok(SecKeyVerifySignature(pubKey
, algorithm
, dataToSign
, signature
, &error
),
904 "SecKeyVerifySignature failed for algorithm %@", algorithm
);
905 CFReleaseNull(error
);
907 CFMutableDataRef modifiedSignature
= CFDataCreateMutable(kCFAllocatorDefault
, 0);
908 CFDataAppend(modifiedSignature
, signature
);
909 *CFDataGetMutableBytePtr(modifiedSignature
) ^= 0xff;
911 ok(!SecKeyVerifySignature(pubKey
, algorithm
, dataToSign
, modifiedSignature
, &error
),
912 "SecKeyVerifySignature succeeded with bad signature for algorithm %@", algorithm
);
913 CFReleaseNull(error
);
915 CFMutableDataRef modifiedDataToSign
= CFDataCreateMutable(kCFAllocatorDefault
, 0);
916 CFDataAppend(modifiedDataToSign
, dataToSign
);
917 *CFDataGetMutableBytePtr(modifiedDataToSign
) ^= 0xff;
919 ok(!SecKeyVerifySignature(pubKey
, algorithm
, modifiedDataToSign
, signature
, &error
),
920 "SecKeyVerifySignature succeeded with bad data for algorithm %@", algorithm
);
921 CFReleaseNull(error
);
923 CFReleaseNull(modifiedDataToSign
);
924 CFReleaseNull(modifiedSignature
);
925 CFReleaseNull(signature
);
927 CFReleaseNull(dataToSign
);
930 CFReleaseNull(testData
);
933 CFReleaseNull(pubKey
);
934 CFReleaseNull(privKey
);
937 /* Test basic add delete update copy matching stuff. */
938 #define kTestCount ((3 * kKeyGenTestCount) + kKeyGen2TestCount + kTestSupportedCount + kCreateWithDataTestCount \
939 + kCopyAttributesTestCount + kCopyPublicKeyTestCount + kSignAndVerifyTestCount)
940 static void tests(void)
942 /* Comment out lines below for testing generating all common key sizes,
943 disabled now for speed reasons. */
947 testkeygen(2056); // Stranged sized for edge cases in padding.
953 testsupportedalgos(768);
954 testcreatewithdata(768);
955 testcopyattributes(768);
956 testcopypublickey(768);
960 int si_40_seckey(int argc
, char *const *argv
)
962 plan_tests(kTestCount
);