diff options
author | Martin Schanzenbach <mschanzenbach@posteo.de> | 2020-10-16 13:09:21 +0200 |
---|---|---|
committer | Martin Schanzenbach <mschanzenbach@posteo.de> | 2020-10-16 13:09:21 +0200 |
commit | 2e494a18a1c2eab9776478b7eb29590f530d0109 (patch) | |
tree | 0008be4f8299aba18d330ba17e28f6a33553c365 /src | |
parent | 30e8dd5bbe3ee00942e5f9aa303429249c8e9b3d (diff) | |
download | gnunet-2e494a18a1c2eab9776478b7eb29590f530d0109.tar.gz gnunet-2e494a18a1c2eab9776478b7eb29590f530d0109.zip |
GNS: New symmetric crypto
Diffstat (limited to 'src')
-rw-r--r-- | src/gnsrecord/gnsrecord_crypto.c | 115 |
1 files changed, 89 insertions, 26 deletions
diff --git a/src/gnsrecord/gnsrecord_crypto.c b/src/gnsrecord/gnsrecord_crypto.c index 5c7330998..9c551a936 100644 --- a/src/gnsrecord/gnsrecord_crypto.c +++ b/src/gnsrecord/gnsrecord_crypto.c | |||
@@ -37,6 +37,61 @@ | |||
37 | 37 | ||
38 | #define LOG(kind, ...) GNUNET_log_from (kind, "gnsrecord", __VA_ARGS__) | 38 | #define LOG(kind, ...) GNUNET_log_from (kind, "gnsrecord", __VA_ARGS__) |
39 | 39 | ||
40 | ssize_t | ||
41 | ecdsa_symmetric_decrypt ( | ||
42 | const void *block, | ||
43 | size_t size, | ||
44 | const unsigned char *key, | ||
45 | const unsigned char *ctr, | ||
46 | void *result) | ||
47 | { | ||
48 | gcry_cipher_hd_t handle; | ||
49 | int rc; | ||
50 | |||
51 | GNUNET_assert (0 == gcry_cipher_open (&handle, GCRY_CIPHER_AES256, | ||
52 | GCRY_CIPHER_MODE_CTR, 0)); | ||
53 | rc = gcry_cipher_setkey (handle, | ||
54 | key, | ||
55 | GNUNET_CRYPTO_AES_KEY_LENGTH); | ||
56 | GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY)); | ||
57 | rc = gcry_cipher_setctr (handle, | ||
58 | ctr, | ||
59 | GNUNET_CRYPTO_AES_KEY_LENGTH / 2); | ||
60 | GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY)); | ||
61 | GNUNET_assert (0 == gcry_cipher_decrypt (handle, result, size, block, size)); | ||
62 | gcry_cipher_close (handle); | ||
63 | return size; | ||
64 | } | ||
65 | |||
66 | |||
67 | |||
68 | ssize_t | ||
69 | ecdsa_symmetric_encrypt ( | ||
70 | const void *block, | ||
71 | size_t size, | ||
72 | const unsigned char *key, | ||
73 | const unsigned char *ctr, | ||
74 | void *result) | ||
75 | { | ||
76 | gcry_cipher_hd_t handle; | ||
77 | int rc; | ||
78 | |||
79 | GNUNET_assert (0 == gcry_cipher_open (&handle, GCRY_CIPHER_AES256, | ||
80 | GCRY_CIPHER_MODE_CTR, 0)); | ||
81 | rc = gcry_cipher_setkey (handle, | ||
82 | key, | ||
83 | GNUNET_CRYPTO_AES_KEY_LENGTH); | ||
84 | GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY)); | ||
85 | rc = gcry_cipher_setctr (handle, | ||
86 | ctr, | ||
87 | GNUNET_CRYPTO_AES_KEY_LENGTH / 2); | ||
88 | GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY)); | ||
89 | GNUNET_assert (0 == gcry_cipher_encrypt (handle, result, size, block, size)); | ||
90 | gcry_cipher_close (handle); | ||
91 | return size; | ||
92 | } | ||
93 | |||
94 | |||
40 | 95 | ||
41 | /** | 96 | /** |
42 | * Derive session key and iv from label and public key. | 97 | * Derive session key and iv from label and public key. |
@@ -47,25 +102,31 @@ | |||
47 | * @param pub public key to use for KDF | 102 | * @param pub public key to use for KDF |
48 | */ | 103 | */ |
49 | static void | 104 | static void |
50 | derive_block_aes_key (struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, | 105 | derive_block_aes_key (unsigned char *ctr, |
51 | struct GNUNET_CRYPTO_SymmetricSessionKey *skey, | 106 | unsigned char *key, |
52 | const char *label, | 107 | const char *label, |
108 | uint64_t exp, | ||
53 | const struct GNUNET_CRYPTO_EcdsaPublicKey *pub) | 109 | const struct GNUNET_CRYPTO_EcdsaPublicKey *pub) |
54 | { | 110 | { |
55 | static const char ctx_key[] = "gns-aes-ctx-key"; | 111 | static const char ctx_key[] = "gns-aes-ctx-key"; |
56 | static const char ctx_iv[] = "gns-aes-ctx-iv"; | 112 | static const char ctx_iv[] = "gns-aes-ctx-iv"; |
57 | 113 | ||
58 | GNUNET_CRYPTO_kdf (skey, sizeof(struct GNUNET_CRYPTO_SymmetricSessionKey), | 114 | GNUNET_CRYPTO_kdf (key, GNUNET_CRYPTO_AES_KEY_LENGTH, |
59 | ctx_key, strlen (ctx_key), | 115 | ctx_key, strlen (ctx_key), |
60 | pub, sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey), | 116 | pub, sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey), |
61 | label, strlen (label), | 117 | label, strlen (label), |
62 | NULL, 0); | 118 | NULL, 0); |
63 | GNUNET_CRYPTO_kdf (iv, sizeof(struct | 119 | memset (ctr, 0, GNUNET_CRYPTO_AES_KEY_LENGTH / 2); |
64 | GNUNET_CRYPTO_SymmetricInitializationVector), | 120 | /** 4 byte nonce **/ |
121 | GNUNET_CRYPTO_kdf (ctr, 4, | ||
65 | ctx_iv, strlen (ctx_iv), | 122 | ctx_iv, strlen (ctx_iv), |
66 | pub, sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey), | 123 | pub, sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey), |
67 | label, strlen (label), | 124 | label, strlen (label), |
68 | NULL, 0); | 125 | NULL, 0); |
126 | /** Expiration time 64 bit. **/ | ||
127 | memcpy (ctr + 4, &exp, sizeof (exp)); | ||
128 | /** Set counter part to 1 **/ | ||
129 | ctr[15] |= 0x01; | ||
69 | } | 130 | } |
70 | 131 | ||
71 | 132 | ||
@@ -93,8 +154,8 @@ block_create_ecdsa (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, | |||
93 | struct GNUNET_GNSRECORD_Block *block; | 154 | struct GNUNET_GNSRECORD_Block *block; |
94 | struct GNUNET_GNSRECORD_EcdsaBlock *ecblock; | 155 | struct GNUNET_GNSRECORD_EcdsaBlock *ecblock; |
95 | struct GNUNET_CRYPTO_EcdsaPrivateKey *dkey; | 156 | struct GNUNET_CRYPTO_EcdsaPrivateKey *dkey; |
96 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | 157 | unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2]; |
97 | struct GNUNET_CRYPTO_SymmetricSessionKey skey; | 158 | unsigned char skey[GNUNET_CRYPTO_AES_KEY_LENGTH]; |
98 | struct GNUNET_GNSRECORD_Data rdc[GNUNET_NZL (rd_count)]; | 159 | struct GNUNET_GNSRECORD_Data rdc[GNUNET_NZL (rd_count)]; |
99 | uint32_t rd_count_nbo; | 160 | uint32_t rd_count_nbo; |
100 | struct GNUNET_TIME_Absolute now; | 161 | struct GNUNET_TIME_Absolute now; |
@@ -144,10 +205,10 @@ block_create_ecdsa (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, | |||
144 | ecblock = &block->ecdsa_block; | 205 | ecblock = &block->ecdsa_block; |
145 | block->type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); | 206 | block->type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); |
146 | ecblock->purpose.size = htonl (sizeof(uint32_t) | 207 | ecblock->purpose.size = htonl (sizeof(uint32_t) |
147 | + payload_len | 208 | + payload_len |
148 | + sizeof(struct | 209 | + sizeof(struct |
149 | GNUNET_CRYPTO_EccSignaturePurpose) | 210 | GNUNET_CRYPTO_EccSignaturePurpose) |
150 | + sizeof(struct GNUNET_TIME_AbsoluteNBO)); | 211 | + sizeof(struct GNUNET_TIME_AbsoluteNBO)); |
151 | ecblock->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN); | 212 | ecblock->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN); |
152 | ecblock->expiration_time = GNUNET_TIME_absolute_hton (expire); | 213 | ecblock->expiration_time = GNUNET_TIME_absolute_hton (expire); |
153 | /* encrypt and sign */ | 214 | /* encrypt and sign */ |
@@ -156,17 +217,18 @@ block_create_ecdsa (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, | |||
156 | "gns"); | 217 | "gns"); |
157 | GNUNET_CRYPTO_ecdsa_key_get_public (dkey, | 218 | GNUNET_CRYPTO_ecdsa_key_get_public (dkey, |
158 | &ecblock->derived_key); | 219 | &ecblock->derived_key); |
159 | derive_block_aes_key (&iv, | 220 | derive_block_aes_key (ctr, |
160 | &skey, | 221 | skey, |
161 | label, | 222 | label, |
223 | ecblock->expiration_time.abs_value_us__, | ||
162 | pkey); | 224 | pkey); |
163 | GNUNET_break (payload_len + sizeof(uint32_t) == | 225 | GNUNET_break (payload_len + sizeof(uint32_t) == |
164 | GNUNET_CRYPTO_symmetric_encrypt (payload, | 226 | ecdsa_symmetric_encrypt (payload, |
165 | payload_len | 227 | payload_len |
166 | + sizeof(uint32_t), | 228 | + sizeof(uint32_t), |
167 | &skey, | 229 | skey, |
168 | &iv, | 230 | ctr, |
169 | &ecblock[1])); | 231 | &ecblock[1])); |
170 | } | 232 | } |
171 | if (GNUNET_OK != | 233 | if (GNUNET_OK != |
172 | GNUNET_CRYPTO_ecdsa_sign_ (dkey, | 234 | GNUNET_CRYPTO_ecdsa_sign_ (dkey, |
@@ -326,8 +388,8 @@ block_decrypt_ecdsa (const struct GNUNET_GNSRECORD_EcdsaBlock *block, | |||
326 | size_t payload_len = ntohl (block->purpose.size) | 388 | size_t payload_len = ntohl (block->purpose.size) |
327 | - sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) | 389 | - sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) |
328 | - sizeof(struct GNUNET_TIME_AbsoluteNBO); | 390 | - sizeof(struct GNUNET_TIME_AbsoluteNBO); |
329 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | 391 | unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2]; |
330 | struct GNUNET_CRYPTO_SymmetricSessionKey skey; | 392 | unsigned char key[GNUNET_CRYPTO_AES_KEY_LENGTH]; |
331 | 393 | ||
332 | if (ntohl (block->purpose.size) < | 394 | if (ntohl (block->purpose.size) < |
333 | sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) | 395 | sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) |
@@ -336,18 +398,19 @@ block_decrypt_ecdsa (const struct GNUNET_GNSRECORD_EcdsaBlock *block, | |||
336 | GNUNET_break_op (0); | 398 | GNUNET_break_op (0); |
337 | return GNUNET_SYSERR; | 399 | return GNUNET_SYSERR; |
338 | } | 400 | } |
339 | derive_block_aes_key (&iv, | 401 | derive_block_aes_key (ctr, |
340 | &skey, | 402 | key, |
341 | label, | 403 | label, |
404 | block->expiration_time.abs_value_us__, | ||
342 | zone_key); | 405 | zone_key); |
343 | { | 406 | { |
344 | char payload[payload_len]; | 407 | char payload[payload_len]; |
345 | uint32_t rd_count; | 408 | uint32_t rd_count; |
346 | 409 | ||
347 | GNUNET_break (payload_len == | 410 | GNUNET_break (payload_len == |
348 | GNUNET_CRYPTO_symmetric_decrypt (&block[1], payload_len, | 411 | ecdsa_symmetric_decrypt (&block[1], payload_len, |
349 | &skey, &iv, | 412 | key, ctr, |
350 | payload)); | 413 | payload)); |
351 | GNUNET_memcpy (&rd_count, | 414 | GNUNET_memcpy (&rd_count, |
352 | payload, | 415 | payload, |
353 | sizeof(uint32_t)); | 416 | sizeof(uint32_t)); |