GNUnet  0.11.x
Data Structures | Macros | Functions
gnsrecord_crypto.c File Reference

API for GNS record-related crypto. More...

#include "platform.h"
#include "gnunet_util_lib.h"
#include "gnunet_constants.h"
#include "gnunet_signatures.h"
#include "gnunet_arm_service.h"
#include "gnunet_gnsrecord_lib.h"
#include "gnunet_dnsparser_lib.h"
#include "gnunet_tun_lib.h"
Include dependency graph for gnsrecord_crypto.c:

Go to the source code of this file.

Data Structures

struct  KeyCacheLine
 Line in cache mapping private keys to public keys. More...
 

Macros

#define LOG(kind, ...)   GNUNET_log_from (kind, "gnsrecord", __VA_ARGS__)
 
#define CSIZE   64
 

Functions

static void derive_block_aes_key (struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, struct GNUNET_CRYPTO_SymmetricSessionKey *skey, const char *label, const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
 Derive session key and iv from label and public key. More...
 
struct GNUNET_GNSRECORD_Blockblock_create (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey, struct GNUNET_TIME_Absolute expire, const char *label, const struct GNUNET_GNSRECORD_Data *rd, unsigned int rd_count)
 Sign name and records. More...
 
struct GNUNET_GNSRECORD_BlockGNUNET_GNSRECORD_block_create (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, struct GNUNET_TIME_Absolute expire, const char *label, const struct GNUNET_GNSRECORD_Data *rd, unsigned int rd_count)
 Sign name and records. More...
 
struct GNUNET_GNSRECORD_BlockGNUNET_GNSRECORD_block_create2 (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, struct GNUNET_TIME_Absolute expire, const char *label, const struct GNUNET_GNSRECORD_Data *rd, unsigned int rd_count)
 Sign name and records, cache derived public key (also keeps the private key in static memory, so do not use this function if keeping the private key in the process'es RAM is a major issue). More...
 
int GNUNET_GNSRECORD_block_verify (const struct GNUNET_GNSRECORD_Block *block)
 Check if a signature is valid. More...
 
int GNUNET_GNSRECORD_block_decrypt (const struct GNUNET_GNSRECORD_Block *block, const struct GNUNET_CRYPTO_EcdsaPublicKey *zone_key, const char *label, GNUNET_GNSRECORD_RecordCallback proc, void *proc_cls)
 Decrypt block. More...
 
void GNUNET_GNSRECORD_query_from_private_key (const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, const char *label, struct GNUNET_HashCode *query)
 Calculate the DHT query for a given label in a given zone. More...
 
void GNUNET_GNSRECORD_query_from_public_key (const struct GNUNET_CRYPTO_EcdsaPublicKey *pub, const char *label, struct GNUNET_HashCode *query)
 Calculate the DHT query for a given label in a given zone. More...
 

Detailed Description

API for GNS record-related crypto.

Author
Martin Schanzenbach
Matthias Wachs
Christian Grothoff

Definition in file gnsrecord_crypto.c.

Macro Definition Documentation

◆ LOG

#define LOG (   kind,
  ... 
)    GNUNET_log_from (kind, "gnsrecord", __VA_ARGS__)

Definition at line 38 of file gnsrecord_crypto.c.

◆ CSIZE

#define CSIZE   64

Function Documentation

◆ derive_block_aes_key()

static void derive_block_aes_key ( struct GNUNET_CRYPTO_SymmetricInitializationVector iv,
struct GNUNET_CRYPTO_SymmetricSessionKey skey,
const char *  label,
const struct GNUNET_CRYPTO_EcdsaPublicKey pub 
)
static

Derive session key and iv from label and public key.

Parameters
ivinitialization vector to initialize
skeysession key to initialize
labellabel to use for KDF
pubpublic key to use for KDF

Next time we break protocol (v12) we harmonize the KDF usage in GNS: We use the strings above as salt and the public key as IKM similar to how derive_h is done in crypto_ecc.c.

Definition at line 50 of file gnsrecord_crypto.c.

References GNUNET_CRYPTO_kdf().

Referenced by block_create(), and GNUNET_GNSRECORD_block_decrypt().

54 {
55  static const char ctx_key[] = "gns-aes-ctx-key";
56  static const char ctx_iv[] = "gns-aes-ctx-iv";
62 #ifdef LSD001
64  ctx_key, strlen (ctx_key),
65  pub, sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey),
66  label, strlen (label),
67  NULL, 0);
68  GNUNET_CRYPTO_kdf (iv, sizeof(struct
70  ctx_iv, strlen (ctx_iv),
71  pub, sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey),
72  label, strlen (label),
73  NULL, 0);
74 #else
76  pub, sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey),
77  label, strlen (label),
78  ctx_key, strlen (ctx_key),
79  NULL, 0);
80  GNUNET_CRYPTO_kdf (iv, sizeof(struct
82  pub, sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey),
83  label, strlen (label),
84  ctx_iv, strlen (ctx_iv),
85  NULL, 0);
86 #endif
87 }
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
int GNUNET_CRYPTO_kdf(void *result, size_t out_len, const void *xts, size_t xts_len, const void *skm, size_t skm_len,...)
Derive key.
Definition: crypto_kdf.c:89
Here is the call graph for this function:
Here is the caller graph for this function:

◆ block_create()

struct GNUNET_GNSRECORD_Block* block_create ( const struct GNUNET_CRYPTO_EcdsaPrivateKey key,
const struct GNUNET_CRYPTO_EcdsaPublicKey pkey,
struct GNUNET_TIME_Absolute  expire,
const char *  label,
const struct GNUNET_GNSRECORD_Data rd,
unsigned int  rd_count 
)

Sign name and records.

Parameters
keythe private key
pkeyassociated public key
expireblock expiration
labelthe name for the records
rdrecord data
rd_countnumber of records
Returns
NULL on error (block too large)

Definition at line 102 of file gnsrecord_crypto.c.

References GNUNET_TIME_Absolute::abs_value_us, derive_block_aes_key(), GNUNET_GNSRECORD_Block::derived_key, GNUNET_GNSRECORD_Data::expiration_time, GNUNET_GNSRECORD_Block::expiration_time, GNUNET_GNSRECORD_Data::flags, GNUNET_assert, GNUNET_break, GNUNET_CRYPTO_ecdsa_key_get_public(), GNUNET_CRYPTO_ecdsa_private_key_derive(), GNUNET_CRYPTO_ecdsa_sign(), GNUNET_CRYPTO_symmetric_encrypt(), GNUNET_free, GNUNET_GNSRECORD_MAX_BLOCK_SIZE, GNUNET_GNSRECORD_records_get_size(), GNUNET_GNSRECORD_records_serialize(), GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION, GNUNET_malloc, GNUNET_memcpy, GNUNET_OK, GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN, GNUNET_TIME_absolute_add(), GNUNET_TIME_absolute_get(), GNUNET_TIME_absolute_hton(), payload, GNUNET_CRYPTO_EccSignaturePurpose::purpose, GNUNET_GNSRECORD_Block::purpose, GNUNET_TIME_Relative::rel_value_us, GNUNET_GNSRECORD_Block::signature, and GNUNET_CRYPTO_EccSignaturePurpose::size.

Referenced by GNUNET_GNSRECORD_block_create(), and GNUNET_GNSRECORD_block_create2().

108 {
109  ssize_t payload_len = GNUNET_GNSRECORD_records_get_size (rd_count,
110  rd);
111  struct GNUNET_GNSRECORD_Block *block;
112  struct GNUNET_CRYPTO_EcdsaPrivateKey *dkey;
115  struct GNUNET_GNSRECORD_Data rdc[GNUNET_NZL (rd_count)];
116  uint32_t rd_count_nbo;
117  struct GNUNET_TIME_Absolute now;
118 
119  if (payload_len < 0)
120  {
121  GNUNET_break (0);
122  return NULL;
123  }
124  if (payload_len > GNUNET_GNSRECORD_MAX_BLOCK_SIZE)
125  {
126  GNUNET_break (0);
127  return NULL;
128  }
129  /* convert relative to absolute times */
130  now = GNUNET_TIME_absolute_get ();
131  for (unsigned int i = 0; i < rd_count; i++)
132  {
133  rdc[i] = rd[i];
134  if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
135  {
136  struct GNUNET_TIME_Relative t;
137 
138  /* encrypted blocks must never have relative expiration times, convert! */
139  rdc[i].flags &= ~GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
140  t.rel_value_us = rdc[i].expiration_time;
141  rdc[i].expiration_time = GNUNET_TIME_absolute_add (now, t).abs_value_us;
142  }
143  }
144  /* serialize */
145  rd_count_nbo = htonl (rd_count);
146  {
147  char payload[sizeof(uint32_t) + payload_len];
148 
150  &rd_count_nbo,
151  sizeof(uint32_t));
152  GNUNET_assert (payload_len ==
154  rdc,
155  payload_len,
156  &payload[sizeof(uint32_t)
157  ]));
158  block = GNUNET_malloc (sizeof(struct GNUNET_GNSRECORD_Block)
159  + sizeof(uint32_t)
160  + payload_len);
161  block->purpose.size = htonl (sizeof(uint32_t)
162  + payload_len
163  + sizeof(struct
165  + sizeof(struct GNUNET_TIME_AbsoluteNBO));
167  block->expiration_time = GNUNET_TIME_absolute_hton (expire);
168  /* encrypt and sign */
170  label,
171  "gns");
173  &block->derived_key);
175  &skey,
176  label,
177  pkey);
178  GNUNET_break (payload_len + sizeof(uint32_t) ==
180  payload_len
181  + sizeof(uint32_t),
182  &skey,
183  &iv,
184  &block[1]));
185  }
186  if (GNUNET_OK !=
188  &block->purpose,
189  &block->signature))
190  {
191  GNUNET_break (0);
192  GNUNET_free (dkey);
193  GNUNET_free (block);
194  return NULL;
195  }
196  GNUNET_free (dkey);
197  return block;
198 }
struct GNUNET_TIME_AbsoluteNBO expiration_time
Expiration time of the block.
GNUNET_NETWORK_STRUCT_END ssize_t GNUNET_GNSRECORD_records_get_size(unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Calculate how many bytes we will need to serialize the given records.
uint32_t purpose
What does this signature vouch for? This must contain a GNUNET_SIGNATURE_PURPOSE_XXX constant (from g...
ssize_t GNUNET_GNSRECORD_records_serialize(unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd, size_t dest_size, char *dest)
Serialize the given records to the given destination buffer.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_GNSRECORD_MAX_BLOCK_SIZE
Maximum size of a value that can be stored in a GNS block.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_add(struct GNUNET_TIME_Absolute start, struct GNUNET_TIME_Relative duration)
Add a given relative duration to the given start time.
Definition: time.c:395
Private ECC key encoded for transmission.
static struct GNUNET_SCHEDULER_Task * t
Main task.
Information we have in an encrypted block with record data (i.e.
Time for absolute time used by GNUnet, in microseconds and in network byte order. ...
uint64_t abs_value_us
The actual value.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
header of what an ECC signature signs this must be followed by "size - 8" bytes of the actual signed ...
int GNUNET_CRYPTO_ecdsa_sign(const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, struct GNUNET_CRYPTO_EcdsaSignature *sig)
ECDSA Sign a given block.
Definition: crypto_ecc.c:928
ssize_t GNUNET_CRYPTO_symmetric_encrypt(const void *block, size_t size, const struct GNUNET_CRYPTO_SymmetricSessionKey *sessionkey, const struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, void *result)
Encrypt a block using a symmetric sessionkey.
uint32_t size
How many bytes does this signature sign? (including this purpose header); in network byte order (!)...
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
void GNUNET_CRYPTO_ecdsa_key_get_public(const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Extract the public key for the given private key.
Definition: crypto_ecc.c:239
static unsigned long long payload
How much data are we currently storing in the database?
static void derive_block_aes_key(struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, struct GNUNET_CRYPTO_SymmetricSessionKey *skey, const char *label, const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Derive session key and iv from label and public key.
#define GNUNET_NZL(l)
Macro used to avoid using 0 for the length of a variable-size array (Non-Zero-Length).
struct GNUNET_CRYPTO_EcdsaSignature signature
Signature of the block.
#define GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN
Signature of a gnunet naming system record block.
Time for absolute times used by GNUnet, in microseconds.
This flag is currently unused; former RF_PENDING flag.
struct GNUNET_CRYPTO_EcdsaPrivateKey * GNUNET_CRYPTO_ecdsa_private_key_derive(const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, const char *label, const char *context)
Derive a private key from a given private key and a label.
Definition: crypto_ecc.c:1293
struct GNUNET_CRYPTO_EccSignaturePurpose purpose
Number of bytes signed; also specifies the number of bytes of encrypted data that follow...
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:657
struct GNUNET_CRYPTO_EcdsaPublicKey derived_key
Derived key used for signing; hash of this is the query.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
Here is the call graph for this function:
Here is the caller graph for this function: