Tor 0.4.9.0-alpha-dev
crypto_rsa_nss.c
1/* Copyright (c) 2001, Matej Pfajfar.
2 * Copyright (c) 2001-2004, Roger Dingledine.
3 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
4 * Copyright (c) 2007-2021, The Tor Project, Inc. */
5/* See LICENSE for licensing information */
6
7/**
8 * \file crypto_rsa.c
9 * \brief NSS implementations of our RSA code.
10 **/
11
13
16#include "lib/ctime/di_ops.h"
18#include "lib/fs/files.h"
19#include "lib/intmath/cmp.h"
20#include "lib/intmath/muldiv.h"
21#include "lib/log/log.h"
22#include "lib/log/util_bug.h"
23
24#include <string.h>
25
26DISABLE_GCC_WARNING("-Wstrict-prototypes")
27#include <keyhi.h>
28#include <pk11pub.h>
29#include <secder.h>
30ENABLE_GCC_WARNING("-Wstrict-prototypes")
31
32#ifdef ENABLE_OPENSSL
33#include <openssl/rsa.h>
34#include <openssl/evp.h>
35#endif
36
37/** Declaration for crypto_pk_t structure. */
39{
40 SECKEYPrivateKey *seckey;
41 SECKEYPublicKey *pubkey;
42};
43
44/** Return true iff <b>key</b> contains the private-key portion of the RSA
45 * key. */
46int
48{
49 return key && key->seckey;
50}
51
52/** used by tortls.c: wrap a SecKEYPublicKey in a crypto_pk_t. Take ownership
53 * of the RSA object. */
55crypto_pk_new_from_nss_pubkey(struct SECKEYPublicKeyStr *pub)
56{
57 crypto_pk_t *result = tor_malloc_zero(sizeof(crypto_pk_t));
58 result->pubkey = pub;
59 return result;
60}
61
62/** Return the SECKEYPublicKey for the provided crypto_pk_t. */
63const SECKEYPublicKey *
64crypto_pk_get_nss_pubkey(const crypto_pk_t *key)
65{
66 tor_assert(key);
67 return key->pubkey;
68}
69
70/** Return the SECKEYPrivateKey for the provided crypto_pk_t, or NULL if it
71 * does not exist. */
72const SECKEYPrivateKey *
73crypto_pk_get_nss_privkey(const crypto_pk_t *key)
74{
75 tor_assert(key);
76 return key->seckey;
77}
78
79#ifdef ENABLE_OPENSSL
80/** used by tortls.c: wrap an RSA* in a crypto_pk_t. Take ownership of the
81 * RSA object. */
83crypto_new_pk_from_openssl_rsa_(RSA *rsa)
84{
85 crypto_pk_t *pk = NULL;
86 unsigned char *buf = NULL;
87 int len = i2d_RSAPublicKey(rsa, &buf);
88 RSA_free(rsa);
89
90 if (len < 0 || buf == NULL)
91 goto end;
92
93 pk = crypto_pk_asn1_decode((const char *)buf, len);
94
95 end:
96 if (buf)
97 OPENSSL_free(buf);
98 return pk;
99}
100
101/** Helper, used by tor-gencert.c. Return the RSA from a
102 * crypto_pk_t. */
103struct rsa_st *
104crypto_pk_get_openssl_rsa_(crypto_pk_t *pk)
105{
106 size_t buflen = crypto_pk_keysize(pk)*16;
107 unsigned char *buf = tor_malloc_zero(buflen);
108 const unsigned char *cp = buf;
109 RSA *rsa = NULL;
110
111 int used = crypto_pk_asn1_encode_private(pk, (char*)buf, buflen);
112 if (used < 0)
113 goto end;
114 rsa = d2i_RSAPrivateKey(NULL, &cp, used);
115
116 end:
117 memwipe(buf, 0, buflen);
118 tor_free(buf);
119 return rsa;
120}
121
122/** used by tortls.c: get an equivalent EVP_PKEY* for a crypto_pk_t. Iff
123 * private is set, include the private-key portion of the key. Return a valid
124 * pointer on success, and NULL on failure. */
125MOCK_IMPL(struct evp_pkey_st *,
126crypto_pk_get_openssl_evp_pkey_,(crypto_pk_t *pk, int private))
127{
128 size_t buflen = crypto_pk_keysize(pk)*16;
129 unsigned char *buf = tor_malloc_zero(buflen);
130 const unsigned char *cp = buf;
131 RSA *rsa = NULL;
132 EVP_PKEY *result = NULL;
133
134 if (private) {
135 int len = crypto_pk_asn1_encode_private(pk, (char*)buf, buflen);
136 if (len < 0)
137 goto end;
138 rsa = d2i_RSAPrivateKey(NULL, &cp, len);
139 } else {
140 int len = crypto_pk_asn1_encode(pk, (char*)buf, buflen);
141 if (len < 0)
142 goto end;
143 rsa = d2i_RSAPublicKey(NULL, &cp, len);
144 }
145 if (!rsa)
146 goto end;
147
148 if (!(result = EVP_PKEY_new()))
149 goto end;
150 if (!(EVP_PKEY_assign_RSA(result, rsa))) {
151 EVP_PKEY_free(result);
152 RSA_free(rsa);
153 result = NULL;
154 }
155
156 end:
157 memwipe(buf, 0, buflen);
158 tor_free(buf);
159 return result;
160}
161#endif /* defined(ENABLE_OPENSSL) */
162
163/** Allocate and return storage for a public key. The key itself will not yet
164 * be set.
165 */
168{
169 crypto_pk_t *result = tor_malloc_zero(sizeof(crypto_pk_t));
170 return result;
171}
172
173/** Release the NSS objects held in <b>key</b> */
174static void
175crypto_pk_clear(crypto_pk_t *key)
176{
177 if (key->pubkey)
178 SECKEY_DestroyPublicKey(key->pubkey);
179 if (key->seckey)
180 SECKEY_DestroyPrivateKey(key->seckey);
181 memset(key, 0, sizeof(crypto_pk_t));
182}
183
184/** Release a reference to an asymmetric key; when all the references
185 * are released, free the key.
186 */
187void
189{
190 if (!key)
191 return;
192
193 crypto_pk_clear(key);
194
195 tor_free(key);
196}
197
198/** Generate a <b>bits</b>-bit new public/private keypair in <b>env</b>.
199 * Return 0 on success, -1 on failure.
200 */
201MOCK_IMPL(int,
203{
204 tor_assert(key);
205
206 PK11RSAGenParams params = {
207 .keySizeInBits = bits,
208 .pe = TOR_RSA_EXPONENT
209 };
210
211 int result = -1;
212 PK11SlotInfo *slot = PK11_GetBestSlot(CKM_RSA_PKCS_KEY_PAIR_GEN, NULL);
213 SECKEYPrivateKey *seckey = NULL;
214 SECKEYPublicKey *pubkey = NULL;
215
216 if (!slot) {
217 crypto_nss_log_errors(LOG_WARN, "getting slot for RSA keygen");
218 goto done;
219 }
220
221 seckey = PK11_GenerateKeyPair(slot, CKM_RSA_PKCS_KEY_PAIR_GEN, &params,
222 &pubkey,
223 PR_FALSE /*isPerm */,
224 PR_FALSE /*isSensitive*/,
225 NULL);
226 if (seckey == NULL || pubkey == NULL) {
227 crypto_nss_log_errors(LOG_WARN, "generating an RSA key");
228 goto done;
229 }
230
231 crypto_pk_clear(key);
232 key->seckey = seckey;
233 key->pubkey = pubkey;
234 seckey = NULL;
235 pubkey = NULL;
236
237 result = 0;
238 done:
239 if (slot)
240 PK11_FreeSlot(slot);
241 if (pubkey)
242 SECKEY_DestroyPublicKey(pubkey);
243 if (seckey)
244 SECKEY_DestroyPrivateKey(seckey);
245
246 return result;
247}
248
249/** Return true iff <b>env</b> is a valid private key.
250 */
251int
253{
254 /* We don't need to do validation here, since unlike OpenSSL, NSS won't let
255 * us load private keys without validating them. */
256 return key && key->seckey;
257}
258
259/** Return true iff <b>env</b> contains a public key whose public exponent
260 * equals 65537.
261 */
262int
264{
265 return key &&
266 key->pubkey &&
267 key->pubkey->keyType == rsaKey &&
268 DER_GetUInteger(&key->pubkey->u.rsa.publicExponent) == TOR_RSA_EXPONENT;
269}
270
271/** Compare two big-endian integers stored in a and b; return a tristate.
272 */
273STATIC int
274secitem_uint_cmp(const SECItem *a, const SECItem *b)
275{
276 const unsigned abits = SECKEY_BigIntegerBitLength(a);
277 const unsigned bbits = SECKEY_BigIntegerBitLength(b);
278
279 if (abits < bbits)
280 return -1;
281 else if (abits > bbits)
282 return 1;
283
284 /* okay, they have the same number of bits set. Get a pair of aligned
285 * pointers to their bytes that are set... */
286 const unsigned nbytes = CEIL_DIV(abits, 8);
287 tor_assert(nbytes <= a->len);
288 tor_assert(nbytes <= b->len);
289
290 const unsigned char *aptr = a->data + (a->len - nbytes);
291 const unsigned char *bptr = b->data + (b->len - nbytes);
292
293 /* And compare them. */
294 return fast_memcmp(aptr, bptr, nbytes);
295}
296
297/** Compare the public-key components of a and b. Return less than 0
298 * if a<b, 0 if a==b, and greater than 0 if a>b. A NULL key is
299 * considered to be less than all non-NULL keys, and equal to itself.
300 *
301 * Note that this may leak information about the keys through timing.
302 */
303int
305{
306 int result;
307 char a_is_non_null = (a != NULL) && (a->pubkey != NULL);
308 char b_is_non_null = (b != NULL) && (b->pubkey != NULL);
309 char an_argument_is_null = !a_is_non_null | !b_is_non_null;
310
311 result = tor_memcmp(&a_is_non_null, &b_is_non_null, sizeof(a_is_non_null));
312 if (an_argument_is_null)
313 return result;
314
315 // This is all Tor uses with this structure.
316 tor_assert(a->pubkey->keyType == rsaKey);
317 tor_assert(b->pubkey->keyType == rsaKey);
318
319 const SECItem *a_n, *a_e, *b_n, *b_e;
320 a_n = &a->pubkey->u.rsa.modulus;
321 b_n = &b->pubkey->u.rsa.modulus;
322 a_e = &a->pubkey->u.rsa.publicExponent;
323 b_e = &b->pubkey->u.rsa.publicExponent;
324
325 result = secitem_uint_cmp(a_n, b_n);
326 if (result)
327 return result;
328 return secitem_uint_cmp(a_e, b_e);
329}
330
331/** Return the size of the public key modulus in <b>env</b>, in bytes. */
332size_t
334{
335 tor_assert(key);
336 tor_assert(key->pubkey);
337 return SECKEY_PublicKeyStrength(key->pubkey);
338}
339
340/** Return the size of the public key modulus of <b>env</b>, in bits. */
341int
343{
344 tor_assert(key);
345 tor_assert(key->pubkey);
346 return SECKEY_PublicKeyStrengthInBits(key->pubkey);
347}
348
349/**
350 * Make a copy of <b>key</b> and return it.
351 */
354{
355 crypto_pk_t *result = crypto_pk_new();
356 if (key->pubkey)
357 result->pubkey = SECKEY_CopyPublicKey(key->pubkey);
358 if (key->seckey)
359 result->seckey = SECKEY_CopyPrivateKey(key->seckey);
360 return result;
361}
362
363/** For testing: replace dest with src. (Dest must have a refcount
364 * of 1) */
365void
367{
368 crypto_pk_clear(dest);
369 if (src->pubkey)
370 dest->pubkey = SECKEY_CopyPublicKey(src->pubkey);
371}
372
373/** For testing: replace dest with src. (Dest must have a refcount
374 * of 1) */
375void
377{
378 crypto_pk_clear(dest);
379 if (src->pubkey)
380 dest->pubkey = SECKEY_CopyPublicKey(src->pubkey);
381 if (src->seckey)
382 dest->seckey = SECKEY_CopyPrivateKey(src->seckey);
383}
384
385/** Make a real honest-to-goodness copy of <b>env</b>, and return it.
386 * Returns NULL on failure. */
389{
390 // These aren't reference-counted is nss, so it's fine to just
391 // use the same function.
392 return crypto_pk_dup_key(key);
393}
394
395static const CK_RSA_PKCS_OAEP_PARAMS oaep_params = {
396 .hashAlg = CKM_SHA_1,
397 .mgf = CKG_MGF1_SHA1,
398 .source = CKZ_DATA_SPECIFIED,
399 .pSourceData = NULL,
400 .ulSourceDataLen = 0
401};
402static const SECItem oaep_item = {
403 .type = siBuffer,
404 .data = (unsigned char *) &oaep_params,
405 .len = sizeof(oaep_params)
406};
407
408/** Return the mechanism code and parameters for a given padding method when
409 * used with RSA */
410static CK_MECHANISM_TYPE
411padding_to_mechanism(int padding, SECItem **item_out)
412{
413 switch (padding) {
415 *item_out = (SECItem *)&oaep_item;
416 return CKM_RSA_PKCS_OAEP;
417 default:
418 tor_assert_unreached();
419 *item_out = NULL;
420 return CKM_INVALID_MECHANISM;
421 }
422}
423
424/** Encrypt <b>fromlen</b> bytes from <b>from</b> with the public key
425 * in <b>env</b>, using the padding method <b>padding</b>. On success,
426 * write the result to <b>to</b>, and return the number of bytes
427 * written. On failure, return -1.
428 *
429 * <b>tolen</b> is the number of writable bytes in <b>to</b>, and must be
430 * at least the length of the modulus of <b>env</b>.
431 */
432int
433crypto_pk_public_encrypt(crypto_pk_t *env, char *to, size_t tolen,
434 const char *from, size_t fromlen, int padding)
435{
436 tor_assert(env);
437 tor_assert(to);
438 tor_assert(from);
439 tor_assert(tolen < INT_MAX);
440 tor_assert(fromlen < INT_MAX);
441
442 if (BUG(! env->pubkey))
443 return -1;
444
445 unsigned int result_len = 0;
446 SECItem *item = NULL;
447 CK_MECHANISM_TYPE m = padding_to_mechanism(padding, &item);
448
449 SECStatus s = PK11_PubEncrypt(env->pubkey, m, item,
450 (unsigned char *)to, &result_len,
451 (unsigned int)tolen,
452 (const unsigned char *)from,
453 (unsigned int)fromlen,
454 NULL);
455 if (s != SECSuccess) {
456 crypto_nss_log_errors(LOG_WARN, "encrypting to an RSA key");
457 return -1;
458 }
459
460 return (int)result_len;
461}
462
463/** Decrypt <b>fromlen</b> bytes from <b>from</b> with the private key
464 * in <b>env</b>, using the padding method <b>padding</b>. On success,
465 * write the result to <b>to</b>, and return the number of bytes
466 * written. On failure, return -1.
467 *
468 * <b>tolen</b> is the number of writable bytes in <b>to</b>, and must be
469 * at least the length of the modulus of <b>key</b>.
470 */
471int
473 size_t tolen,
474 const char *from, size_t fromlen,
475 int padding, int warnOnFailure)
476{
477 tor_assert(key);
478 tor_assert(to);
479 tor_assert(from);
480 tor_assert(tolen < INT_MAX);
481 tor_assert(fromlen < INT_MAX);
482
483 if (!crypto_pk_key_is_private(key))
484 return -1; /* Not a private key. */
485
486 unsigned int result_len = 0;
487 SECItem *item = NULL;
488 CK_MECHANISM_TYPE m = padding_to_mechanism(padding, &item);
489 SECStatus s = PK11_PrivDecrypt(key->seckey, m, item,
490 (unsigned char *)to, &result_len,
491 (unsigned int)tolen,
492 (const unsigned char *)from,
493 (unsigned int)fromlen);
494
495 if (s != SECSuccess) {
496 const int severity = warnOnFailure ? LOG_WARN : LOG_INFO;
497 crypto_nss_log_errors(severity, "decrypting with an RSA key");
498 return -1;
499 }
500
501 return (int)result_len;
502}
503
504/** Check the signature in <b>from</b> (<b>fromlen</b> bytes long) with the
505 * public key in <b>key</b>, using PKCS1 padding. On success, write the
506 * signed data to <b>to</b>, and return the number of bytes written.
507 * On failure, return -1.
508 *
509 * <b>tolen</b> is the number of writable bytes in <b>to</b>, and must be
510 * at least the length of the modulus of <b>key</b>.
511 */
512MOCK_IMPL(int,
513crypto_pk_public_checksig,(const crypto_pk_t *key, char *to,
514 size_t tolen,
515 const char *from, size_t fromlen))
516{
517 tor_assert(key);
518 tor_assert(to);
519 tor_assert(from);
520 tor_assert(tolen < INT_MAX);
521 tor_assert(fromlen < INT_MAX);
522 tor_assert(key->pubkey);
523
524 SECItem sig = {
525 .type = siBuffer,
526 .data = (unsigned char *) from,
527 .len = (unsigned int) fromlen,
528 };
529 SECItem dsig = {
530 .type = siBuffer,
531 .data = (unsigned char *) to,
532 .len = (unsigned int) tolen
533 };
534 SECStatus s;
535 s = PK11_VerifyRecover(key->pubkey, &sig, &dsig, NULL);
536 if (s != SECSuccess)
537 return -1;
538
539 return (int)dsig.len;
540}
541
542/** Sign <b>fromlen</b> bytes of data from <b>from</b> with the private key in
543 * <b>env</b>, using PKCS1 padding. On success, write the signature to
544 * <b>to</b>, and return the number of bytes written. On failure, return
545 * -1.
546 *
547 * <b>tolen</b> is the number of writable bytes in <b>to</b>, and must be
548 * at least the length of the modulus of <b>env</b>.
549 */
550int
551crypto_pk_private_sign(const crypto_pk_t *key, char *to, size_t tolen,
552 const char *from, size_t fromlen)
553{
554 tor_assert(key);
555 tor_assert(to);
556 tor_assert(from);
557 tor_assert(tolen < INT_MAX);
558 tor_assert(fromlen < INT_MAX);
559
560 if (BUG(!crypto_pk_key_is_private(key)))
561 return -1;
562
563 SECItem sig = {
564 .type = siBuffer,
565 .data = (unsigned char *)to,
566 .len = (unsigned int) tolen
567 };
568 SECItem hash = {
569 .type = siBuffer,
570 .data = (unsigned char *)from,
571 .len = (unsigned int) fromlen
572 };
573 CK_MECHANISM_TYPE m = CKM_RSA_PKCS;
574 SECStatus s = PK11_SignWithMechanism(key->seckey, m, NULL,
575 &sig, &hash);
576
577 if (s != SECSuccess) {
578 crypto_nss_log_errors(LOG_WARN, "signing with an RSA key");
579 return -1;
580 }
581
582 return (int)sig.len;
583}
584
585/* "This has lead to people trading hard-to-find object identifiers and ASN.1
586 * definitions like baseball cards" - Peter Gutmann, "X.509 Style Guide". */
587static const unsigned char RSA_OID[] = {
588 /* RSADSI */ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
589 /* PKCS1 */ 0x01, 0x01,
590 /* RSA */ 0x01
591};
592
593/** ASN.1-encode the public portion of <b>pk</b> into <b>dest</b>.
594 * Return -1 on error, or the number of characters used on success.
595 */
596int
597crypto_pk_asn1_encode(const crypto_pk_t *pk, char *dest, size_t dest_len)
598{
599 tor_assert(pk);
600 if (pk->pubkey == NULL)
601 return -1;
602
603 CERTSubjectPublicKeyInfo *info;
604 info = SECKEY_CreateSubjectPublicKeyInfo(pk->pubkey);
605 if (! info)
606 return -1;
607
608 const SECItem *item = &info->subjectPublicKey;
609 size_t actual_len = (item->len) >> 3; /* bits to bytes */
610 size_t n_used = MIN(actual_len, dest_len);
611 memcpy(dest, item->data, n_used);
612
613 SECKEY_DestroySubjectPublicKeyInfo(info);
614 return (int) n_used;
615}
616
617/** Decode an ASN.1-encoded public key from <b>str</b>; return the result on
618 * success and NULL on failure.
619 */
621crypto_pk_asn1_decode(const char *str, size_t len)
622{
623 tor_assert(str);
624 if (len >= INT_MAX)
625 return NULL;
626 CERTSubjectPublicKeyInfo info = {
627 .algorithm = {
628 .algorithm = {
629 .type = siDEROID,
630 .data = (unsigned char *)RSA_OID,
631 .len = sizeof(RSA_OID)
632 }
633 },
634 .subjectPublicKey = {
635 .type = siBuffer,
636 .data = (unsigned char *)str,
637 .len = (unsigned int)(len << 3) /* bytes to bits */
638 }
639 };
640
641 SECKEYPublicKey *pub = SECKEY_ExtractPublicKey(&info);
642 if (pub == NULL)
643 return NULL;
644
645 crypto_pk_t *result = crypto_pk_new();
646 result->pubkey = pub;
647 return result;
648}
649
650DISABLE_GCC_WARNING("-Wunused-parameter")
651
652/** Given a crypto_pk_t <b>pk</b>, allocate a new buffer containing the Base64
653 * encoding of the DER representation of the private key into the
654 * <b>dest_len</b>-byte buffer in <b>dest</b>.
655 * Return the number of bytes written on success, -1 on failure.
656 */
657int
659 char *dest, size_t destlen)
660{
661 tor_assert(destlen <= INT_MAX);
663 return -1;
664
665 SECKEYPrivateKeyInfo *info = PK11_ExportPrivKeyInfo(pk->seckey, NULL);
666 if (!info)
667 return -1;
668 SECItem *item = &info->privateKey;
669
670 if (destlen < item->len) {
671 SECKEY_DestroyPrivateKeyInfo(info, PR_TRUE);
672 return -1;
673 }
674 int result = (int)item->len;
675 memcpy(dest, item->data, item->len);
676 SECKEY_DestroyPrivateKeyInfo(info, PR_TRUE);
677
678 return result;
679}
680
681/** Given a buffer containing the DER representation of the
682 * private key <b>str</b>, decode and return the result on success, or NULL
683 * on failure.
684 *
685 * If <b>max_bits</b> is nonnegative, reject any key longer than max_bits
686 * without performing any expensive validation on it.
687 */
689crypto_pk_asn1_decode_private(const char *str, size_t len, int max_bits)
690{
691 tor_assert(str);
692 tor_assert(len < INT_MAX);
693 PK11SlotInfo *slot = PK11_GetBestSlot(CKM_RSA_PKCS, NULL);
694 if (!slot)
695 return NULL;
696
697 SECKEYPrivateKeyInfo info = {
698 .algorithm = {
699 .algorithm = {
700 .type = siBuffer,
701 .data = (unsigned char *)RSA_OID,
702 .len = sizeof(RSA_OID)
703 }
704 },
705 .privateKey = {
706 .type = siBuffer,
707 .data = (unsigned char *)str,
708 .len = (int)len,
709 }
710 };
711
712 SECStatus s;
713 SECKEYPrivateKey *seckey = NULL;
714
715 s = PK11_ImportPrivateKeyInfoAndReturnKey(slot, &info,
716 NULL /* nickname */,
717 NULL /* publicValue */,
718 PR_FALSE /* isPerm */,
719 PR_FALSE /* isPrivate */,
720 KU_ALL /* keyUsage */,
721 &seckey, NULL);
722
723 crypto_pk_t *output = NULL;
724
725 if (s == SECSuccess && seckey) {
726 output = crypto_pk_new();
727 output->seckey = seckey;
728 output->pubkey = SECKEY_ConvertToPublicKey(seckey);
729 tor_assert(output->pubkey);
730 } else {
731 crypto_nss_log_errors(LOG_WARN, "decoding an RSA private key");
732 }
733
734 if (! crypto_pk_is_valid_private_key(output)) {
735 crypto_pk_free(output);
736 output = NULL;
737 }
738
739 if (output) {
740 const int bits = SECKEY_PublicKeyStrengthInBits(output->pubkey);
741 if (max_bits >= 0 && bits > max_bits) {
742 log_info(LD_CRYPTO, "Private key longer than expected.");
743 crypto_pk_free(output);
744 output = NULL;
745 }
746 }
747
748 if (slot)
749 PK11_FreeSlot(slot);
750
751 return output;
752}
Header for binascii.c.
Macro definitions for MIN, MAX, and CLAMP.
Headers for crypto_nss_mgt.c.
Headers for crypto_rsa.c.
#define TOR_RSA_EXPONENT
Definition: crypto_rsa.h:37
void crypto_pk_assign_private(crypto_pk_t *dest, const crypto_pk_t *src)
crypto_pk_t * crypto_pk_new(void)
int crypto_pk_cmp_keys(const crypto_pk_t *a, const crypto_pk_t *b)
int crypto_pk_generate_key_with_bits(crypto_pk_t *env, int bits)
size_t crypto_pk_keysize(const crypto_pk_t *env)
int crypto_pk_private_sign(const crypto_pk_t *env, char *to, size_t tolen, const char *from, size_t fromlen)
int crypto_pk_is_valid_private_key(const crypto_pk_t *env)
int crypto_pk_private_decrypt(crypto_pk_t *env, char *to, size_t tolen, const char *from, size_t fromlen, int padding, int warnOnFailure)
#define PK_PKCS1_OAEP_PADDING
Definition: crypto_rsa.h:27
int crypto_pk_asn1_encode(const crypto_pk_t *pk, char *dest, size_t dest_len)
crypto_pk_t * crypto_pk_asn1_decode(const char *str, size_t len)
crypto_pk_t * crypto_pk_copy_full(crypto_pk_t *orig)
int crypto_pk_public_encrypt(crypto_pk_t *env, char *to, size_t tolen, const char *from, size_t fromlen, int padding)
void crypto_pk_assign_public(crypto_pk_t *dest, const crypto_pk_t *src)
crypto_pk_t * crypto_pk_asn1_decode_private(const char *str, size_t len, int max_bits)
int crypto_pk_num_bits(crypto_pk_t *env)
crypto_pk_t * crypto_pk_dup_key(crypto_pk_t *orig)
int crypto_pk_key_is_private(const crypto_pk_t *key)
int crypto_pk_asn1_encode_private(const crypto_pk_t *pk, char *dest, size_t dest_len)
int crypto_pk_public_checksig(const crypto_pk_t *env, char *to, size_t tolen, const char *from, size_t fromlen)
int crypto_pk_public_exponent_ok(const crypto_pk_t *env)
void crypto_pk_free_(crypto_pk_t *env)
void memwipe(void *mem, uint8_t byte, size_t sz)
Definition: crypto_util.c:55
Common functions for cryptographic routines.
int tor_memcmp(const void *a, const void *b, size_t len)
Definition: di_ops.c:31
Headers for di_ops.c.
#define fast_memcmp(a, b, c)
Definition: di_ops.h:28
Wrappers for reading and writing data to files on disk.
Headers for log.c.
#define LD_CRYPTO
Definition: log.h:64
#define LOG_WARN
Definition: log.h:53
#define LOG_INFO
Definition: log.h:45
#define tor_free(p)
Definition: malloc.h:56
Header for muldiv.c.
#define STATIC
Definition: testsupport.h:32
#define MOCK_IMPL(rv, funcname, arglist)
Definition: testsupport.h:133
Macros to manage assertions, fatal and non-fatal.
#define tor_assert(expr)
Definition: util_bug.h:103