GNUnet 0.21.1
crypto_rsa.c File Reference

Chaum-style Blind signatures based on RSA. More...

#include "platform.h"
#include <gcrypt.h>
#include "gnunet_util_lib.h"
#include "benchmark.h"
Include dependency graph for crypto_rsa.c:

Go to the source code of this file.

Data Structures

struct  GNUNET_CRYPTO_RsaPrivateKey
 The private information of an RSA key pair. More...
 
struct  GNUNET_CRYPTO_RsaPublicKey
 The public information of an RSA key pair. More...
 
struct  GNUNET_CRYPTO_RsaSignature
 an RSA signature More...
 
struct  RsaBlindingKey
 RSA blinding key. More...
 
struct  GNUNET_CRYPTO_RsaPublicKeyHeaderP
 Format of the header of a serialized RSA public key. More...
 

Macros

#define LOG(kind, ...)   GNUNET_log_from (kind, "util-crypto-rsa", __VA_ARGS__)
 

Functions

static int key_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp, const char *topname, const char *elems)
 Extract values from an S-expression. More...
 
struct GNUNET_CRYPTO_RsaPrivateKeyGNUNET_CRYPTO_rsa_private_key_create (unsigned int len)
 Create a new private key. More...
 
void GNUNET_CRYPTO_rsa_private_key_free (struct GNUNET_CRYPTO_RsaPrivateKey *key)
 Free memory occupied by the private key. More...
 
size_t GNUNET_CRYPTO_rsa_private_key_encode (const struct GNUNET_CRYPTO_RsaPrivateKey *key, void **buffer)
 Encode the private key in a format suitable for storing it into a file. More...
 
struct GNUNET_CRYPTO_RsaPrivateKeyGNUNET_CRYPTO_rsa_private_key_decode (const void *buf, size_t buf_size)
 Decode the private key from the data-format back to the "normal", internal format. More...
 
struct GNUNET_CRYPTO_RsaPublicKeyGNUNET_CRYPTO_rsa_private_key_get_public (const struct GNUNET_CRYPTO_RsaPrivateKey *priv)
 Extract the public key of the given private key. More...
 
void GNUNET_CRYPTO_rsa_public_key_free (struct GNUNET_CRYPTO_RsaPublicKey *key)
 Free memory occupied by the public key. More...
 
GNUNET_NETWORK_STRUCT_END bool GNUNET_CRYPTO_rsa_public_key_check (const struct GNUNET_CRYPTO_RsaPublicKey *key)
 Check if key is well-formed. More...
 
size_t GNUNET_CRYPTO_rsa_public_key_encode (const struct GNUNET_CRYPTO_RsaPublicKey *key, void **buffer)
 Encode the public key in a format suitable for storing it into a file. More...
 
void GNUNET_CRYPTO_rsa_public_key_hash (const struct GNUNET_CRYPTO_RsaPublicKey *key, struct GNUNET_HashCode *hc)
 Compute hash over the public key. More...
 
struct GNUNET_CRYPTO_RsaPublicKeyGNUNET_CRYPTO_rsa_public_key_decode (const char *buf, size_t len)
 Decode the public key from the data-format back to the "normal", internal format. More...
 
static int rsa_gcd_validate (gcry_mpi_t r, gcry_mpi_t n)
 Test for malicious RSA key. More...
 
static struct RsaBlindingKeyrsa_blinding_key_derive (const struct GNUNET_CRYPTO_RsaPublicKey *pkey, const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks)
 Create a blinding key. More...
 
int GNUNET_CRYPTO_rsa_signature_cmp (const struct GNUNET_CRYPTO_RsaSignature *s1, const struct GNUNET_CRYPTO_RsaSignature *s2)
 Compare the values of two signatures. More...
 
int GNUNET_CRYPTO_rsa_public_key_cmp (const struct GNUNET_CRYPTO_RsaPublicKey *p1, const struct GNUNET_CRYPTO_RsaPublicKey *p2)
 Compare the values of two public keys. More...
 
int GNUNET_CRYPTO_rsa_private_key_cmp (const struct GNUNET_CRYPTO_RsaPrivateKey *p1, const struct GNUNET_CRYPTO_RsaPrivateKey *p2)
 Compare the values of two private keys. More...
 
unsigned int GNUNET_CRYPTO_rsa_public_key_len (const struct GNUNET_CRYPTO_RsaPublicKey *key)
 Obtain the length of the RSA key in bits. More...
 
static void rsa_blinding_key_free (struct RsaBlindingKey *bkey)
 Destroy a blinding key. More...
 
static size_t numeric_mpi_alloc_n_print (gcry_mpi_t v, char **buffer)
 Print an MPI to a newly created buffer. More...
 
static gcry_mpi_t rsa_full_domain_hash (const struct GNUNET_CRYPTO_RsaPublicKey *pkey, const void *message, size_t message_size)
 Computes a full domain hash seeded by the given public key. More...
 
void GNUNET_CRYPTO_rsa_blinded_message_free (struct GNUNET_CRYPTO_RsaBlindedMessage *bm)
 Free memory occupied by blinded message. More...
 
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_rsa_blind (const void *message, size_t message_size, const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks, struct GNUNET_CRYPTO_RsaPublicKey *pkey, struct GNUNET_CRYPTO_RsaBlindedMessage *bm)
 Blinds the given message with the given blinding key. More...
 
static gcry_sexp_t mpi_to_sexp (gcry_mpi_t value)
 Convert an MPI to an S-expression suitable for signature operations. More...
 
static struct GNUNET_CRYPTO_RsaSignaturersa_sign_mpi (const struct GNUNET_CRYPTO_RsaPrivateKey *key, gcry_mpi_t value)
 Sign the given MPI. More...
 
struct GNUNET_CRYPTO_RsaSignatureGNUNET_CRYPTO_rsa_sign_blinded (const struct GNUNET_CRYPTO_RsaPrivateKey *key, const struct GNUNET_CRYPTO_RsaBlindedMessage *bm)
 Sign a blinded value, which must be a full domain hash of a message. More...
 
struct GNUNET_CRYPTO_RsaSignatureGNUNET_CRYPTO_rsa_sign_fdh (const struct GNUNET_CRYPTO_RsaPrivateKey *key, const void *message, size_t message_size)
 Create and sign a full domain hash of a message. More...
 
void GNUNET_CRYPTO_rsa_signature_free (struct GNUNET_CRYPTO_RsaSignature *sig)
 Free memory occupied by signature. More...
 
size_t GNUNET_CRYPTO_rsa_signature_encode (const struct GNUNET_CRYPTO_RsaSignature *sig, void **buffer)
 Encode the given signature in a format suitable for storing it into a file. More...
 
struct GNUNET_CRYPTO_RsaSignatureGNUNET_CRYPTO_rsa_signature_decode (const void *buf, size_t buf_size)
 Decode the signature from the data-format back to the "normal", internal format. More...
 
struct GNUNET_CRYPTO_RsaPublicKeyGNUNET_CRYPTO_rsa_public_key_dup (const struct GNUNET_CRYPTO_RsaPublicKey *key)
 Duplicate the given public key. More...
 
struct GNUNET_CRYPTO_RsaSignatureGNUNET_CRYPTO_rsa_unblind (const struct GNUNET_CRYPTO_RsaSignature *sig, const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks, struct GNUNET_CRYPTO_RsaPublicKey *pkey)
 Unblind a blind-signed signature. More...
 
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_rsa_verify (const void *message, size_t message_size, const struct GNUNET_CRYPTO_RsaSignature *sig, const struct GNUNET_CRYPTO_RsaPublicKey *pkey)
 Verify whether the given hash corresponds to the given signature and the signature is valid with respect to the given public key. More...
 
struct GNUNET_CRYPTO_RsaPrivateKeyGNUNET_CRYPTO_rsa_private_key_dup (const struct GNUNET_CRYPTO_RsaPrivateKey *key)
 Duplicate the given private key. More...
 
struct GNUNET_CRYPTO_RsaSignatureGNUNET_CRYPTO_rsa_signature_dup (const struct GNUNET_CRYPTO_RsaSignature *sig)
 Duplicate the given rsa signature. More...
 

Detailed Description

Chaum-style Blind signatures based on RSA.

Author
Sree Harsha Totakura sreeh.nosp@m.arsh.nosp@m.a@tot.nosp@m.akur.nosp@m.a.in
Christian Grothoff
Jeffrey Burdges burdg.nosp@m.es@g.nosp@m.nunet.nosp@m..org

Definition in file crypto_rsa.c.

Macro Definition Documentation

◆ LOG

#define LOG (   kind,
  ... 
)    GNUNET_log_from (kind, "util-crypto-rsa", __VA_ARGS__)

Definition at line 34 of file crypto_rsa.c.

Function Documentation

◆ key_from_sexp()

static int key_from_sexp ( gcry_mpi_t *  array,
gcry_sexp_t  sexp,
const char *  topname,
const char *  elems 
)
static

Extract values from an S-expression.

Parameters
arraywhere to store the result(s)
sexpS-expression to parse
topnametop-level name in the S-expression that is of interest
elemsnames of the elements to extract
Returns
0 on success

Definition at line 95 of file crypto_rsa.c.

99{
100 gcry_sexp_t list;
101 gcry_sexp_t l2;
102 const char *s;
103 unsigned int idx;
104
105 if (! (list = gcry_sexp_find_token (sexp, topname, 0)))
106 return 1;
107 l2 = gcry_sexp_cadr (list);
108 gcry_sexp_release (list);
109 list = l2;
110 if (! list)
111 return 2;
112 idx = 0;
113 for (s = elems; *s; s++, idx++)
114 {
115 if (! (l2 = gcry_sexp_find_token (list, s, 1)))
116 {
117 for (unsigned int i = 0; i < idx; i++)
118 {
119 gcry_free (array[i]);
120 array[i] = NULL;
121 }
122 gcry_sexp_release (list);
123 return 3; /* required parameter not found */
124 }
125 array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
126 gcry_sexp_release (l2);
127 if (! array[idx])
128 {
129 for (unsigned int i = 0; i < idx; i++)
130 {
131 gcry_free (array[i]);
132 array[i] = NULL;
133 }
134 gcry_sexp_release (list);
135 return 4; /* required parameter is invalid */
136 }
137 }
138 gcry_sexp_release (list);
139 return 0;
140}
static int list
Set if we should print a list of currently running services.
Definition: gnunet-arm.c:69

References list.

Referenced by GNUNET_CRYPTO_rsa_blind(), GNUNET_CRYPTO_rsa_private_key_get_public(), GNUNET_CRYPTO_rsa_public_key_check(), GNUNET_CRYPTO_rsa_public_key_encode(), GNUNET_CRYPTO_rsa_public_key_len(), GNUNET_CRYPTO_rsa_signature_dup(), GNUNET_CRYPTO_rsa_signature_encode(), GNUNET_CRYPTO_rsa_unblind(), rsa_blinding_key_derive(), and rsa_full_domain_hash().

Here is the caller graph for this function:

◆ rsa_gcd_validate()

static int rsa_gcd_validate ( gcry_mpi_t  r,
gcry_mpi_t  n 
)
static

Test for malicious RSA key.

Assuming n is an RSA modulous and r is generated using a call to GNUNET_CRYPTO_kdf_mod_mpi, if gcd(r,n) != 1 then n must be a malicious RSA key designed to deanomize the user.

Parameters
rKDF result
nRSA modulus
Returns
True if gcd(r,n) = 1, False means RSA key is malicious

Definition at line 501 of file crypto_rsa.c.

503{
504 gcry_mpi_t g;
505 int t;
506
507 g = gcry_mpi_new (0);
508 t = gcry_mpi_gcd (g, r, n);
509 gcry_mpi_release (g);
510 return t;
511}
static struct GNUNET_SCHEDULER_Task * t
Main task.

References t.

Referenced by rsa_blinding_key_derive(), and rsa_full_domain_hash().

Here is the caller graph for this function:

◆ rsa_blinding_key_derive()

static struct RsaBlindingKey * rsa_blinding_key_derive ( const struct GNUNET_CRYPTO_RsaPublicKey pkey,
const struct GNUNET_CRYPTO_RsaBlindingKeySecret bks 
)
static

Create a blinding key.

Parameters
lenlength of the key in bits (e.g. 2048)
bkspre-secret to use to derive the blinding key
Returns
the newly created blinding key, NULL if RSA key is malicious

Definition at line 522 of file crypto_rsa.c.

524{
525 const char *xts = "Blinding KDF extractor HMAC key"; /* Trusts bks' randomness more */
526 struct RsaBlindingKey *blind;
527 gcry_mpi_t n;
528
529 blind = GNUNET_new (struct RsaBlindingKey);
530
531 /* Extract the composite n from the RSA public key */
532 GNUNET_assert (0 ==
533 key_from_sexp (&n,
534 pkey->sexp,
535 "rsa",
536 "n"));
537 /* Assert that it at least looks like an RSA key */
538 GNUNET_assert (0 ==
539 gcry_mpi_get_flag (n,
540 GCRYMPI_FLAG_OPAQUE));
542 n,
543 xts, strlen (xts),
544 bks, sizeof(*bks),
545 "Blinding KDF");
546 if (0 == rsa_gcd_validate (blind->r,
547 n))
548 {
549 gcry_mpi_release (blind->r);
550 GNUNET_free (blind);
551 blind = NULL;
552 }
553 gcry_mpi_release (n);
554 return blind;
555}
static int key_from_sexp(gcry_mpi_t *array, gcry_sexp_t sexp, const char *topname, const char *elems)
Extract values from an S-expression.
Definition: crypto_rsa.c:95
static int rsa_gcd_validate(gcry_mpi_t r, gcry_mpi_t n)
Test for malicious RSA key.
Definition: crypto_rsa.c:501
static char * pkey
Public key of the zone to look in, in ASCII.
void GNUNET_CRYPTO_kdf_mod_mpi(gcry_mpi_t *r, gcry_mpi_t n, const void *xts, size_t xts_len, const void *skm, size_t skm_len, const char *ctx)
Deterministically generate a pseudo-random number uniformly from the integers modulo a libgcrypt mpi.
Definition: crypto_kdf.c:95
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
RSA blinding key.
Definition: crypto_rsa.c:77
gcry_mpi_t r
Random value used for blinding.
Definition: crypto_rsa.c:81

References GNUNET_assert, GNUNET_CRYPTO_kdf_mod_mpi(), GNUNET_free, GNUNET_new, key_from_sexp(), pkey, RsaBlindingKey::r, and rsa_gcd_validate().

Referenced by GNUNET_CRYPTO_rsa_blind(), and GNUNET_CRYPTO_rsa_unblind().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rsa_blinding_key_free()

static void rsa_blinding_key_free ( struct RsaBlindingKey bkey)
static

Destroy a blinding key.

Parameters
bkeythe blinding key to destroy

Definition at line 702 of file crypto_rsa.c.

703{
704 gcry_mpi_release (bkey->r);
705 GNUNET_free (bkey);
706}

References GNUNET_free, and RsaBlindingKey::r.

Referenced by GNUNET_CRYPTO_rsa_blind(), and GNUNET_CRYPTO_rsa_unblind().

Here is the caller graph for this function:

◆ numeric_mpi_alloc_n_print()

static size_t numeric_mpi_alloc_n_print ( gcry_mpi_t  v,
char **  buffer 
)
static

Print an MPI to a newly created buffer.

Parameters
vMPI to print.
[out]buffernewly allocated buffer containing the result
Returns
number of bytes stored in buffer

Definition at line 717 of file crypto_rsa.c.

719{
720 size_t n;
721 char *b;
722 size_t rsize;
723
724 gcry_mpi_print (GCRYMPI_FMT_USG,
725 NULL,
726 0,
727 &n,
728 v);
729 b = GNUNET_malloc (n);
730 GNUNET_assert (0 ==
731 gcry_mpi_print (GCRYMPI_FMT_USG,
732 (unsigned char *) b,
733 n,
734 &rsize,
735 v));
736 *buffer = b;
737 return n;
738}
#define GNUNET_malloc(size)
Wrapper around malloc.

References GNUNET_assert, and GNUNET_malloc.

Referenced by GNUNET_CRYPTO_rsa_blind().

Here is the caller graph for this function:

◆ rsa_full_domain_hash()

static gcry_mpi_t rsa_full_domain_hash ( const struct GNUNET_CRYPTO_RsaPublicKey pkey,
const void *  message,
size_t  message_size 
)
static

Computes a full domain hash seeded by the given public key.

This gives a measure of provable security to the Taler exchange against one-more forgery attacks. See: https://eprint.iacr.org/2001/002.pdf http://www.di.ens.fr/~pointche/Documents/Papers/2001_fcA.pdf

Parameters
messagethe message to sign
message_sizenumber of bytes in message
pkeythe public key of the signer
rsizeIf not NULL, the number of bytes actually stored in buffer
Returns
MPI value set to the FDH, NULL if RSA key is malicious

Definition at line 755 of file crypto_rsa.c.

758{
759 gcry_mpi_t r;
760 gcry_mpi_t n;
761 void *xts;
762 size_t xts_len;
763 int ok;
764
765 /* Extract the composite n from the RSA public key */
766 GNUNET_assert (0 ==
767 key_from_sexp (&n,
768 pkey->sexp,
769 "rsa",
770 "n"));
771 /* Assert that it at least looks like an RSA key */
772 GNUNET_assert (0 ==
773 gcry_mpi_get_flag (n,
774 GCRYMPI_FLAG_OPAQUE));
775
776 /* We key with the public denomination key as a homage to RSA-PSS by *
777 * Mihir Bellare and Phillip Rogaway. Doing this lowers the degree *
778 * of the hypothetical polyomial-time attack on RSA-KTI created by a *
779 * polynomial-time one-more forgary attack. Yey seeding! */
781 &xts);
782
784 n,
785 xts, xts_len,
786 message, message_size,
787 "RSA-FDA FTpsW!");
788 GNUNET_free (xts);
789 ok = rsa_gcd_validate (r, n);
790 gcry_mpi_release (n);
791 if (ok)
792 return r;
793 gcry_mpi_release (r);
794 return NULL;
795}
size_t GNUNET_CRYPTO_rsa_public_key_encode(const struct GNUNET_CRYPTO_RsaPublicKey *key, void **buffer)
Encode the public key in a format suitable for storing it into a file.
Definition: crypto_rsa.c:325

References GNUNET_assert, GNUNET_CRYPTO_kdf_mod_mpi(), GNUNET_CRYPTO_rsa_public_key_encode(), GNUNET_free, key_from_sexp(), pkey, RsaBlindingKey::r, and rsa_gcd_validate().

Referenced by GNUNET_CRYPTO_rsa_blind(), GNUNET_CRYPTO_rsa_sign_fdh(), and GNUNET_CRYPTO_rsa_verify().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mpi_to_sexp()

static gcry_sexp_t mpi_to_sexp ( gcry_mpi_t  value)
static

Convert an MPI to an S-expression suitable for signature operations.

Parameters
valuepointer to the data to convert
Returns
converted s-expression

Definition at line 894 of file crypto_rsa.c.

895{
896 gcry_sexp_t data = NULL;
897
898 GNUNET_assert (0 ==
899 gcry_sexp_build (&data,
900 NULL,
901 "(data (flags raw) (value %M))",
902 value));
903 return data;
904}
static char * data
The data to insert into the dht.
static char * value
Value of the record to add/remove.

References data, GNUNET_assert, and value.

Referenced by GNUNET_CRYPTO_rsa_verify(), and rsa_sign_mpi().

Here is the caller graph for this function:

◆ rsa_sign_mpi()

static struct GNUNET_CRYPTO_RsaSignature * rsa_sign_mpi ( const struct GNUNET_CRYPTO_RsaPrivateKey key,
gcry_mpi_t  value 
)
static

Sign the given MPI.

Parameters
keyprivate key to use for the signing
valuethe MPI to sign
Returns
NULL on error, signature on success

Definition at line 915 of file crypto_rsa.c.

917{
918 struct GNUNET_CRYPTO_RsaSignature *sig;
919 gcry_sexp_t data;
920 gcry_sexp_t result;
921 int rc;
922
924
925 if (0 !=
926 (rc = gcry_pk_sign (&result,
927 data,
928 key->sexp)))
929 {
931 _ ("RSA signing failed at %s:%d: %s\n"),
932 __FILE__,
933 __LINE__,
934 gcry_strerror (rc));
935 gcry_sexp_release (data);
936 GNUNET_break (0);
937 return NULL;
938 }
939
940 /* Lenstra protection was first added to libgcrypt 1.6.4
941 * with commit c17f84bd02d7ee93845e92e20f6ddba814961588.
942 */
943#if GCRYPT_VERSION_NUMBER < 0x010604
944 /* verify signature (guards against Lenstra's attack with fault injection...) */
945 struct GNUNET_CRYPTO_RsaPublicKey *public_key =
947 if (0 !=
948 gcry_pk_verify (result,
949 data,
950 public_key->sexp))
951 {
952 GNUNET_break (0);
954 gcry_sexp_release (data);
955 gcry_sexp_release (result);
956 return NULL;
957 }
959#endif
960
961 /* return signature */
962 gcry_sexp_release (data);
964 sig->sexp = result;
965 return sig;
966}
static gcry_sexp_t mpi_to_sexp(gcry_mpi_t value)
Convert an MPI to an S-expression suitable for signature operations.
Definition: crypto_rsa.c:894
#define LOG(kind,...)
Definition: crypto_rsa.c:34
struct GNUNET_HashCode key
The key used in the DHT.
static int result
Global testing status.
void GNUNET_CRYPTO_rsa_public_key_free(struct GNUNET_CRYPTO_RsaPublicKey *key)
Free memory occupied by the public key.
Definition: crypto_rsa.c:268
struct GNUNET_CRYPTO_RsaPublicKey * GNUNET_CRYPTO_rsa_private_key_get_public(const struct GNUNET_CRYPTO_RsaPrivateKey *priv)
Extract the public key of the given private key.
Definition: crypto_rsa.c:233
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_WARNING
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
The public information of an RSA key pair.
Definition: crypto_rsa.c:53
gcry_sexp_t sexp
Libgcrypt S-expression for the RSA public key.
Definition: crypto_rsa.c:57
an RSA signature
Definition: crypto_rsa.c:65
gcry_sexp_t sexp
Libgcrypt S-expression for the RSA signature.
Definition: crypto_rsa.c:69

References _, data, GNUNET_break, GNUNET_CRYPTO_rsa_private_key_get_public(), GNUNET_CRYPTO_rsa_public_key_free(), GNUNET_ERROR_TYPE_WARNING, GNUNET_new, key, LOG, mpi_to_sexp(), result, GNUNET_CRYPTO_RsaPublicKey::sexp, GNUNET_CRYPTO_RsaSignature::sexp, and value.

Referenced by GNUNET_CRYPTO_rsa_sign_blinded(), and GNUNET_CRYPTO_rsa_sign_fdh().

Here is the call graph for this function:
Here is the caller graph for this function: