X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Finclude%2Fgnunet_crypto_lib.h;h=1e2af892509c8b97bfa939ace9d26a1e08a51b02;hb=211fd52268a5ae7856273dd8d8b3b3ed427beadb;hp=c9c7348421f97a2eeabd2cc0f5105c515b2a51ca;hpb=a339af3c6f42f5dfcd6117e831296399f7e31b95;p=oweals%2Fgnunet.git diff --git a/src/include/gnunet_crypto_lib.h b/src/include/gnunet_crypto_lib.h index c9c734842..1e2af8925 100644 --- a/src/include/gnunet_crypto_lib.h +++ b/src/include/gnunet_crypto_lib.h @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Christian Grothoff (and other contributing authors) + (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2012 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -71,7 +71,6 @@ enum GNUNET_CRYPTO_Quality */ #define GNUNET_CRYPTO_AES_KEY_LENGTH (256/8) - /** * @brief Length of RSA encrypted data (2048 bit) * @@ -84,26 +83,68 @@ enum GNUNET_CRYPTO_Quality */ #define GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH 256 - /** - * Length of an RSA KEY (d,e,len), 2048 bit (=256 octests) key d, 2 byte e + * Length of an RSA KEY (n,e,len), 2048 bit (=256 octests) key n, 2 byte e */ #define GNUNET_CRYPTO_RSA_KEY_LENGTH 258 - /** * Length of a hash value */ -#define GNUNET_CRYPTO_HASH_LENGTH 512/8 +#define GNUNET_CRYPTO_HASH_LENGTH (512/8) + +/** + * Maximum length of an ECC signature. + * Note: round up to multiple of 8 minus 2 for alignment. + */ +#define GNUNET_CRYPTO_ECC_SIGNATURE_DATA_ENCODING_LENGTH 190 + +/** + * Maximum length of the public key (q-point, Q = dP) when encoded. + */ +#define GNUNET_CRYPTO_ECC_MAX_PUBLIC_KEY_LENGTH 140 + /** * The private information of an RSA key pair. */ struct GNUNET_CRYPTO_RsaPrivateKey; +/** + * The private information of an ECC private key. + */ +struct GNUNET_CRYPTO_EccPrivateKey; + + +GNUNET_NETWORK_STRUCT_BEGIN + +/** + * GNUnet mandates a certain format for the encoding + * of private RSA key information that is provided + * by the RSA implementations. This format is used + * to serialize a private RSA key (typically when + * writing it to disk). + */ +struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded +{ + /** + * Total size of the structure, in bytes, in big-endian! + */ + uint16_t len GNUNET_PACKED; + uint16_t sizen GNUNET_PACKED; /* in big-endian! */ + uint16_t sizee GNUNET_PACKED; /* in big-endian! */ + uint16_t sized GNUNET_PACKED; /* in big-endian! */ + uint16_t sizep GNUNET_PACKED; /* in big-endian! */ + uint16_t sizeq GNUNET_PACKED; /* in big-endian! */ + uint16_t sizedmp1 GNUNET_PACKED; /* in big-endian! */ + uint16_t sizedmq1 GNUNET_PACKED; /* in big-endian! */ + /* followed by the actual values */ +}; +GNUNET_NETWORK_STRUCT_END + /** - * @brief 0-terminated ASCII encoding of a GNUNET_HashCode. + * @brief 0-terminated ASCII encoding of a struct GNUNET_HashCode. */ struct GNUNET_CRYPTO_HashAsciiEncoded { @@ -111,6 +152,15 @@ struct GNUNET_CRYPTO_HashAsciiEncoded }; +/** + * @brief 0-terminated ASCII encoding of a 'struct GNUNET_ShortHashCode'. + */ +struct GNUNET_CRYPTO_ShortHashAsciiEncoded +{ + unsigned char short_encoding[53]; +}; + + /** * @brief an RSA signature @@ -121,6 +171,8 @@ struct GNUNET_CRYPTO_RsaSignature }; +GNUNET_NETWORK_STRUCT_BEGIN + /** * @brief header of what an RSA signature signs * this must be followed by "size - 8" bytes of @@ -182,6 +234,85 @@ struct GNUNET_CRYPTO_RsaEncryptedData }; +/** + * @brief header of what an ECC signature signs + * this must be followed by "size - 8" bytes of + * the actual signed data + */ +struct GNUNET_CRYPTO_EccSignaturePurpose +{ + /** + * How many bytes does this signature sign? + * (including this purpose header); in network + * byte order (!). + */ + uint32_t size GNUNET_PACKED; + + /** + * What does this signature vouch for? This + * must contain a GNUNET_SIGNATURE_PURPOSE_XXX + * constant (from gnunet_signatures.h). In + * network byte order! + */ + uint32_t purpose GNUNET_PACKED; + +}; + + +/** + * @brief an ECC signature + */ +struct GNUNET_CRYPTO_EccSignature +{ + /** + * Overall size of the signature data. + */ + uint16_t size; + + /** + * S-expression, padded with zeros. + */ + char sexpr[GNUNET_CRYPTO_ECC_SIGNATURE_DATA_ENCODING_LENGTH]; +}; + + +/** + * Public ECC key (always for NIST P-521) encoded in a format suitable + * for network transmission as created using 'gcry_sexp_sprint'. + */ +struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded +{ + /** + * Size of the encoding, in network byte order. + */ + uint16_t size; + + /** + * Actual length of the q-point binary encoding. + */ + uint16_t len; + + /** + * 0-padded q-point in binary encoding (GCRYPT_MPI_FMT_USG). + */ + unsigned char key[GNUNET_CRYPTO_ECC_MAX_PUBLIC_KEY_LENGTH]; +}; + + +struct GNUNET_CRYPTO_EccPrivateKeyBinaryEncoded +{ + /** + * Overall size of the private key. + */ + uint16_t size; + + /* followd by S-expression, opaque to applications */ + + /* FIXME: consider defining padding to make this a fixed-size struct */ + +}; + + /** * @brief type for session keys */ @@ -197,13 +328,13 @@ struct GNUNET_CRYPTO_AesSessionKey */ uint32_t crc32 GNUNET_PACKED; }; - +GNUNET_NETWORK_STRUCT_END /** * @brief IV for sym cipher * * NOTE: must be smaller (!) in size than the - * GNUNET_HashCode. + * struct GNUNET_HashCode. */ struct GNUNET_CRYPTO_AesInitializationVector { @@ -222,6 +353,48 @@ struct GNUNET_CRYPTO_AuthKey /* **************** Functions and Macros ************* */ +/** + * Seed a weak random generator. Only GNUNET_CRYPTO_QUALITY_WEAK-mode generator + * can be seeded. + * + * @param seed the seed to use + */ +void +GNUNET_CRYPTO_seed_weak_random (int32_t seed); + + +/** + * Perform an incremental step in a CRC16 (for TCP/IP) calculation. + * + * @param sum current sum, initially 0 + * @param buf buffer to calculate CRC over (must be 16-bit aligned) + * @param len number of bytes in hdr, must be multiple of 2 + * @return updated crc sum (must be subjected to GNUNET_CRYPTO_crc16_finish to get actual crc16) + */ +uint32_t +GNUNET_CRYPTO_crc16_step (uint32_t sum, const void *buf, size_t len); + + +/** + * Convert results from GNUNET_CRYPTO_crc16_step to final crc16. + * + * @param sum cummulative sum + * @return crc16 value + */ +uint16_t +GNUNET_CRYPTO_crc16_finish (uint32_t sum); + + +/** + * Calculate the checksum of a buffer in one step. + * + * @param buf buffer to calculate CRC over (must be 16-bit aligned) + * @param len number of bytes in hdr, must be multiple of 2 + * @return crc16 value + */ +uint16_t +GNUNET_CRYPTO_crc16_n (const void *buf, size_t len); + /** * Compute the CRC32 checksum for the first len @@ -231,8 +404,8 @@ struct GNUNET_CRYPTO_AuthKey * @param len the length of the buffer in bytes * @return the resulting CRC32 checksum */ -int32_t GNUNET_CRYPTO_crc32_n (const void *buf, - size_t len); +int32_t +GNUNET_CRYPTO_crc32_n (const void *buf, size_t len); /** @@ -242,19 +415,19 @@ int32_t GNUNET_CRYPTO_crc32_n (const void *buf, * @param i the upper limit (exclusive) for the random number * @return a random value in the interval [0,i) (exclusive). */ -uint32_t GNUNET_CRYPTO_random_u32 (enum GNUNET_CRYPTO_Quality mode, - uint32_t i); +uint32_t +GNUNET_CRYPTO_random_u32 (enum GNUNET_CRYPTO_Quality mode, uint32_t i); /** - * Random on unsigned 64-bit values. + * Random on unsigned 64-bit values. * * @param mode desired quality of the random number * @param max value returned will be in range [0,max) (exclusive) * @return random 64-bit number */ -uint64_t GNUNET_CRYPTO_random_u64 (enum GNUNET_CRYPTO_Quality mode, - uint64_t max); +uint64_t +GNUNET_CRYPTO_random_u64 (enum GNUNET_CRYPTO_Quality mode, uint64_t max); /** @@ -264,8 +437,8 @@ uint64_t GNUNET_CRYPTO_random_u64 (enum GNUNET_CRYPTO_Quality mode, * @param n the size of the array * @return the permutation array (allocated from heap) */ -unsigned int *GNUNET_CRYPTO_random_permute (enum GNUNET_CRYPTO_Quality mode, - unsigned int n); +unsigned int * +GNUNET_CRYPTO_random_permute (enum GNUNET_CRYPTO_Quality mode, unsigned int n); /** @@ -273,8 +446,9 @@ unsigned int *GNUNET_CRYPTO_random_permute (enum GNUNET_CRYPTO_Quality mode, * * @param key key to initialize */ -void GNUNET_CRYPTO_aes_create_session_key (struct GNUNET_CRYPTO_AesSessionKey - *key); +void +GNUNET_CRYPTO_aes_create_session_key (struct GNUNET_CRYPTO_AesSessionKey *key); + /** * Check that a new session key is well-formed. @@ -282,8 +456,9 @@ void GNUNET_CRYPTO_aes_create_session_key (struct GNUNET_CRYPTO_AesSessionKey * @param key key to check * @return GNUNET_OK if the key is valid */ -int GNUNET_CRYPTO_aes_check_session_key (const struct - GNUNET_CRYPTO_AesSessionKey *key); +int +GNUNET_CRYPTO_aes_check_session_key (const struct GNUNET_CRYPTO_AesSessionKey + *key); /** @@ -297,13 +472,11 @@ int GNUNET_CRYPTO_aes_check_session_key (const struct * for streams. * @return the size of the encrypted block, -1 for errors */ -ssize_t GNUNET_CRYPTO_aes_encrypt (const void *block, - size_t len, - const struct GNUNET_CRYPTO_AesSessionKey - *sessionkey, - const struct - GNUNET_CRYPTO_AesInitializationVector *iv, - void *result); +ssize_t +GNUNET_CRYPTO_aes_encrypt (const void *block, size_t len, + const struct GNUNET_CRYPTO_AesSessionKey *sessionkey, + const struct GNUNET_CRYPTO_AesInitializationVector + *iv, void *result); /** @@ -316,11 +489,11 @@ ssize_t GNUNET_CRYPTO_aes_encrypt (const void *block, * @param result address to store the result at * @return -1 on failure, size of decrypted block on success */ -ssize_t GNUNET_CRYPTO_aes_decrypt (const void *block, - size_t size, - const struct GNUNET_CRYPTO_AesSessionKey *sessionkey, - const struct GNUNET_CRYPTO_AesInitializationVector *iv, - void *result); +ssize_t +GNUNET_CRYPTO_aes_decrypt (const void *block, size_t size, + const struct GNUNET_CRYPTO_AesSessionKey *sessionkey, + const struct GNUNET_CRYPTO_AesInitializationVector + *iv, void *result); /** @@ -333,8 +506,8 @@ ssize_t GNUNET_CRYPTO_aes_decrypt (const void *block, */ void GNUNET_CRYPTO_aes_derive_iv (struct GNUNET_CRYPTO_AesInitializationVector *iv, - const struct GNUNET_CRYPTO_AesSessionKey *skey, void *salt, - size_t salt_len, ...); + const struct GNUNET_CRYPTO_AesSessionKey *skey, + const void *salt, size_t salt_len, ...); /** @@ -347,8 +520,8 @@ GNUNET_CRYPTO_aes_derive_iv (struct GNUNET_CRYPTO_AesInitializationVector *iv, */ void GNUNET_CRYPTO_aes_derive_iv_v (struct GNUNET_CRYPTO_AesInitializationVector *iv, - const struct GNUNET_CRYPTO_AesSessionKey *skey, void *salt, - size_t salt_len, const va_list argp); + const struct GNUNET_CRYPTO_AesSessionKey *skey, + const void *salt, size_t salt_len, va_list argp); /** @@ -357,20 +530,82 @@ GNUNET_CRYPTO_aes_derive_iv_v (struct GNUNET_CRYPTO_AesInitializationVector *iv, * @param result where to store the encoding (struct GNUNET_CRYPTO_HashAsciiEncoded can be * safely cast to char*, a '\\0' termination is set). */ -void GNUNET_CRYPTO_hash_to_enc (const GNUNET_HashCode * block, - struct GNUNET_CRYPTO_HashAsciiEncoded - *result); +void +GNUNET_CRYPTO_hash_to_enc (const struct GNUNET_HashCode * block, + struct GNUNET_CRYPTO_HashAsciiEncoded *result); + + +/** + * Convert short hash to ASCII encoding. + * + * @param block the hash code + * @param result where to store the encoding (struct GNUNET_CRYPTO_ShortHashAsciiEncoded can be + * safely cast to char*, a '\\0' termination is set). + */ +void +GNUNET_CRYPTO_short_hash_to_enc (const struct GNUNET_CRYPTO_ShortHashCode * block, + struct GNUNET_CRYPTO_ShortHashAsciiEncoded *result); + + +/** + * Convert ASCII encoding back to a 'struct GNUNET_HashCode' + * + * @param enc the encoding + * @param enclen number of characters in 'enc' (without 0-terminator, which can be missing) + * @param result where to store the GNUNET_CRYPTO_hash code + * @return GNUNET_OK on success, GNUNET_SYSERR if result has the wrong encoding + */ +int +GNUNET_CRYPTO_hash_from_string2 (const char *enc, size_t enclen, + struct GNUNET_HashCode * result); /** - * Convert ASCII encoding back to GNUNET_CRYPTO_hash + * Convert ASCII encoding back to a 'struct GNUNET_CRYPTO_ShortHash' + * * @param enc the encoding + * @param enclen number of characters in 'enc' (without 0-terminator, which can be missing) * @param result where to store the GNUNET_CRYPTO_hash code * @return GNUNET_OK on success, GNUNET_SYSERR if result has the wrong encoding */ -int GNUNET_CRYPTO_hash_from_string (const char *enc, - GNUNET_HashCode * result); +int +GNUNET_CRYPTO_short_hash_from_string2 (const char *enc, size_t enclen, + struct GNUNET_CRYPTO_ShortHashCode * result); + +/** + * Convert ASCII encoding back to struct GNUNET_HashCode + * + * @param enc the encoding + * @param result where to store the hash code + * @return GNUNET_OK on success, GNUNET_SYSERR if result has the wrong encoding + */ +#define GNUNET_CRYPTO_hash_from_string(enc, result) \ + GNUNET_CRYPTO_hash_from_string2 (enc, strlen(enc), result) + + +/** + * Convert ASCII encoding back to a 'struct GNUNET_CRYPTO_ShortHash' + * + * @param enc the encoding + * @param result where to store the GNUNET_CRYPTO_ShortHash + * @return GNUNET_OK on success, GNUNET_SYSERR if result has the wrong encoding + */ +#define GNUNET_CRYPTO_short_hash_from_string(enc, result) \ + GNUNET_CRYPTO_short_hash_from_string2 (enc, strlen(enc), result) + + +/** + * Compare function for ShortHashCodes, producing a total ordering + * of all hashcodes. + * + * @param h1 some hash code + * @param h2 some hash code + * @return 1 if h1 > h2, -1 if h1 < h2 and 0 if h1 == h2. + */ +int +GNUNET_CRYPTO_short_hash_cmp (const struct GNUNET_CRYPTO_ShortHashCode * h1, + const struct GNUNET_CRYPTO_ShortHashCode * h2); /** * Compute the distance between 2 hashcodes. @@ -383,8 +618,9 @@ int GNUNET_CRYPTO_hash_from_string (const char *enc, * @param b some hash code * @return number between 0 and UINT32_MAX */ -uint32_t GNUNET_CRYPTO_hash_distance_u32 (const GNUNET_HashCode * a, - const GNUNET_HashCode * b); +uint32_t +GNUNET_CRYPTO_hash_distance_u32 (const struct GNUNET_HashCode * a, + const struct GNUNET_HashCode * b); /** @@ -394,9 +630,44 @@ uint32_t GNUNET_CRYPTO_hash_distance_u32 (const GNUNET_HashCode * a, * @param size size of the block * @param ret pointer to where to write the hashcode */ -void GNUNET_CRYPTO_hash (const void *block, - size_t size, - GNUNET_HashCode * ret); +void +GNUNET_CRYPTO_hash (const void *block, size_t size, struct GNUNET_HashCode * ret); + + +/** + * Compute short (256-bit) hash of a given block. + * + * @param block the data to hash + * @param size size of the block + * @param ret pointer to where to write the hashcode + */ +void +GNUNET_CRYPTO_short_hash (const void *block, size_t size, + struct GNUNET_CRYPTO_ShortHashCode * ret); + + +/** + * Double short (256-bit) hash to create a long hash. + * + * @param sh short hash to double + * @param dh where to store the (doubled) long hash (not really a hash) + */ +void +GNUNET_CRYPTO_short_hash_double (const struct GNUNET_CRYPTO_ShortHashCode *sh, + struct GNUNET_HashCode *dh); + + +/** + * Truncate doubled short hash back to a short hash. + * + * @param dh doubled short hash to reduce again + * @param sh where to store the short hash + * @return GNUNET_OK on success, GNUNET_SYSERR if this was not a + * doubled short hash + */ +int +GNUNET_CRYPTO_short_hash_from_truncation (const struct GNUNET_HashCode *dh, + struct GNUNET_CRYPTO_ShortHashCode *sh); /** @@ -407,11 +678,10 @@ void GNUNET_CRYPTO_hash (const void *block, * @param plaintext_len length of plaintext * @param hmac where to store the hmac */ -void +void GNUNET_CRYPTO_hmac (const struct GNUNET_CRYPTO_AuthKey *key, - const void *plaintext, - size_t plaintext_len, - GNUNET_HashCode *hmac); + const void *plaintext, size_t plaintext_len, + struct GNUNET_HashCode * hmac); /** @@ -422,7 +692,7 @@ GNUNET_CRYPTO_hmac (const struct GNUNET_CRYPTO_AuthKey *key, * @param res resulting hash, NULL on error */ typedef void (*GNUNET_CRYPTO_HashCompletedCallback) (void *cls, - const GNUNET_HashCode * + const struct GNUNET_HashCode * res); @@ -434,7 +704,6 @@ struct GNUNET_CRYPTO_FileHashContext; /** * Compute the hash of an entire file. * - * @param sched scheduler to use * @param priority scheduling priority to use * @param filename name of file to hash * @param blocksize number of bytes to process in one task @@ -443,12 +712,10 @@ struct GNUNET_CRYPTO_FileHashContext; * @return NULL on (immediate) errror */ struct GNUNET_CRYPTO_FileHashContext * -GNUNET_CRYPTO_hash_file (struct GNUNET_SCHEDULER_Handle *sched, - enum GNUNET_SCHEDULER_Priority priority, - const char *filename, - size_t blocksize, - GNUNET_CRYPTO_HashCompletedCallback callback, - void *callback_cls); +GNUNET_CRYPTO_hash_file (enum GNUNET_SCHEDULER_Priority priority, + const char *filename, size_t blocksize, + GNUNET_CRYPTO_HashCompletedCallback callback, + void *callback_cls); /** @@ -466,8 +733,9 @@ GNUNET_CRYPTO_hash_file_cancel (struct GNUNET_CRYPTO_FileHashContext *fhc); * @param mode desired quality level * @param result hash code that is randomized */ -void GNUNET_CRYPTO_hash_create_random (enum GNUNET_CRYPTO_Quality mode, - GNUNET_HashCode * result); +void +GNUNET_CRYPTO_hash_create_random (enum GNUNET_CRYPTO_Quality mode, + struct GNUNET_HashCode * result); /** @@ -475,11 +743,12 @@ void GNUNET_CRYPTO_hash_create_random (enum GNUNET_CRYPTO_Quality mode, * * @param a some hash code * @param b some hash code - * @param result set to b - a + * @param result set to b - a */ -void GNUNET_CRYPTO_hash_difference (const GNUNET_HashCode * a, - const GNUNET_HashCode * b, - GNUNET_HashCode * result); +void +GNUNET_CRYPTO_hash_difference (const struct GNUNET_HashCode * a, + const struct GNUNET_HashCode * b, + struct GNUNET_HashCode * result); /** @@ -489,9 +758,10 @@ void GNUNET_CRYPTO_hash_difference (const GNUNET_HashCode * a, * @param delta some hash code * @param result set to a + delta */ -void GNUNET_CRYPTO_hash_sum (const GNUNET_HashCode * a, - const GNUNET_HashCode * delta, - GNUNET_HashCode * result); +void +GNUNET_CRYPTO_hash_sum (const struct GNUNET_HashCode * a, + const struct GNUNET_HashCode * delta, + struct GNUNET_HashCode * result); /** @@ -499,11 +769,11 @@ void GNUNET_CRYPTO_hash_sum (const GNUNET_HashCode * a, * * @param a some hash code * @param b some hash code - * @param result set to a ^ b + * @param result set to a ^ b */ -void GNUNET_CRYPTO_hash_xor (const GNUNET_HashCode * a, - const GNUNET_HashCode * b, - GNUNET_HashCode * result); +void +GNUNET_CRYPTO_hash_xor (const struct GNUNET_HashCode * a, const struct GNUNET_HashCode * b, + struct GNUNET_HashCode * result); /** @@ -513,11 +783,11 @@ void GNUNET_CRYPTO_hash_xor (const GNUNET_HashCode * a, * @param skey set to a valid session key * @param iv set to a valid initialization vector */ -void GNUNET_CRYPTO_hash_to_aes_key (const GNUNET_HashCode * hc, - struct GNUNET_CRYPTO_AesSessionKey *skey, - struct - GNUNET_CRYPTO_AesInitializationVector - *iv); +void +GNUNET_CRYPTO_hash_to_aes_key (const struct GNUNET_HashCode * hc, + struct GNUNET_CRYPTO_AesSessionKey *skey, + struct GNUNET_CRYPTO_AesInitializationVector + *iv); /** @@ -527,12 +797,12 @@ void GNUNET_CRYPTO_hash_to_aes_key (const GNUNET_HashCode * hc, * @param bit index into the hashcode, [0...159] * @return Bit \a bit from hashcode \a code, -1 for invalid index */ -int GNUNET_CRYPTO_hash_get_bit (const GNUNET_HashCode * code, - unsigned int bit); +int +GNUNET_CRYPTO_hash_get_bit (const struct GNUNET_HashCode * code, unsigned int bit); /** * Determine how many low order bits match in two - * GNUNET_HashCodes. i.e. - 010011 and 011111 share + * struct GNUNET_HashCodes. i.e. - 010011 and 011111 share * the first two lowest order bits, and therefore the * return value is two (NOT XOR distance, nor how many * bits match absolutely!). @@ -542,7 +812,9 @@ int GNUNET_CRYPTO_hash_get_bit (const GNUNET_HashCode * code, * * @return the number of bits that match */ -unsigned int GNUNET_CRYPTO_hash_matching_bits(const GNUNET_HashCode *first, const GNUNET_HashCode *second); +unsigned int +GNUNET_CRYPTO_hash_matching_bits (const struct GNUNET_HashCode * first, + const struct GNUNET_HashCode * second); /** @@ -553,8 +825,8 @@ unsigned int GNUNET_CRYPTO_hash_matching_bits(const GNUNET_HashCode *first, cons * @param h2 some hash code * @return 1 if h1 > h2, -1 if h1 < h2 and 0 if h1 == h2. */ -int GNUNET_CRYPTO_hash_cmp (const GNUNET_HashCode * h1, - const GNUNET_HashCode * h2); +int +GNUNET_CRYPTO_hash_cmp (const struct GNUNET_HashCode * h1, const struct GNUNET_HashCode * h2); /** @@ -566,9 +838,10 @@ int GNUNET_CRYPTO_hash_cmp (const GNUNET_HashCode * h1, * @param target some hash code * @return -1 if h1 is closer, 1 if h2 is closer and 0 if h1==h2. */ -int GNUNET_CRYPTO_hash_xorcmp (const GNUNET_HashCode * h1, - const GNUNET_HashCode * h2, - const GNUNET_HashCode * target); +int +GNUNET_CRYPTO_hash_xorcmp (const struct GNUNET_HashCode * h1, + const struct GNUNET_HashCode * h2, + const struct GNUNET_HashCode * target); /** @@ -580,11 +853,10 @@ int GNUNET_CRYPTO_hash_xorcmp (const GNUNET_HashCode * h1, * @param argp pair of void * & size_t for context chunks, terminated by NULL */ void -GNUNET_CRYPTO_hmac_derive_key_v(struct GNUNET_CRYPTO_AuthKey *key, - const struct GNUNET_CRYPTO_AesSessionKey *rkey, - const void *salt, - const size_t salt_len, - const va_list argp); +GNUNET_CRYPTO_hmac_derive_key_v (struct GNUNET_CRYPTO_AuthKey *key, + const struct GNUNET_CRYPTO_AesSessionKey *rkey, + const void *salt, size_t salt_len, + va_list argp); /** @@ -596,11 +868,9 @@ GNUNET_CRYPTO_hmac_derive_key_v(struct GNUNET_CRYPTO_AuthKey *key, * @param ... pair of void * & size_t for context chunks, terminated by NULL */ void -GNUNET_CRYPTO_hmac_derive_key(struct GNUNET_CRYPTO_AuthKey *key, - const struct GNUNET_CRYPTO_AesSessionKey *rkey, - const void *salt, - const size_t salt_len, - ...); +GNUNET_CRYPTO_hmac_derive_key (struct GNUNET_CRYPTO_AuthKey *key, + const struct GNUNET_CRYPTO_AesSessionKey *rkey, + const void *salt, size_t salt_len, ...); /** * @brief Derive key @@ -612,14 +882,12 @@ GNUNET_CRYPTO_hmac_derive_key(struct GNUNET_CRYPTO_AuthKey *key, * @param xts_len length of xts * @param skm source key material * @param skm_len length of skm - * @param ctx context info - * @param ctx_len length of ctx * @return GNUNET_YES on success */ int -GNUNET_CRYPTO_hkdf (void *result, const unsigned long long out_len, - int xtr_algo, int prf_algo, const void *xts, const size_t xts_len, - const void *skm, const size_t skm_len, ...); +GNUNET_CRYPTO_hkdf (void *result, size_t out_len, int xtr_algo, int prf_algo, + const void *xts, size_t xts_len, const void *skm, + size_t skm_len, ...); /** @@ -636,9 +904,9 @@ GNUNET_CRYPTO_hkdf (void *result, const unsigned long long out_len, * @return GNUNET_YES on success */ int -GNUNET_CRYPTO_hkdf_v (void *result, const unsigned long long out_len, - int xtr_algo, int prf_algo, const void *xts, const size_t xts_len, - const void *skm, const size_t skm_len, const va_list argp); +GNUNET_CRYPTO_hkdf_v (void *result, size_t out_len, int xtr_algo, int prf_algo, + const void *xts, size_t xts_len, const void *skm, + size_t skm_len, va_list argp); /** @@ -653,9 +921,9 @@ GNUNET_CRYPTO_hkdf_v (void *result, const unsigned long long out_len, * @return GNUNET_YES on success */ int -GNUNET_CRYPTO_kdf_v (void *result, const unsigned long long out_len, - const void *xts, const size_t xts_len, const void *skm, - const size_t skm_len, const va_list argp); +GNUNET_CRYPTO_kdf_v (void *result, size_t out_len, const void *xts, + size_t xts_len, const void *skm, size_t skm_len, + va_list argp); /** @@ -670,17 +938,53 @@ GNUNET_CRYPTO_kdf_v (void *result, const unsigned long long out_len, * @return GNUNET_YES on success */ int -GNUNET_CRYPTO_kdf (void *result, const unsigned long long out_len, - const void *xts, const size_t xts_len, const void *skm, - const size_t skm_len, ...); +GNUNET_CRYPTO_kdf (void *result, size_t out_len, const void *xts, + size_t xts_len, const void *skm, size_t skm_len, ...); + + +/** + * Convert a public key to a string. + * + * @param pub key to convert + * @return string representing 'pub' + */ +char * +GNUNET_CRYPTO_rsa_public_key_to_string (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pub); + + +/** + * Convert a string representing a public key to a public key. + * + * @param enc encoded public key + * @param enclen number of bytes in enc (without 0-terminator) + * @param pub where to store the public key + * @return GNUNET_OK on success + */ +int +GNUNET_CRYPTO_rsa_public_key_from_string (const char *enc, + size_t enclen, + struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pub); + + +/** + * Encode the private key in a format suitable for + * storing it into a file. + * @return encoding of the private key + */ +struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded * +GNUNET_CRYPTO_rsa_encode_key (const struct GNUNET_CRYPTO_RsaPrivateKey *hostkey); /** - * Create a new private key. Caller must free return value. + * Decode the private key from the data-format back + * to the "normal", internal format. * - * @return fresh private key + * @param buf the buffer where the private key data is stored + * @param len the length of the data in 'buffer' + * @return NULL on error */ -struct GNUNET_CRYPTO_RsaPrivateKey *GNUNET_CRYPTO_rsa_key_create (void); +struct GNUNET_CRYPTO_RsaPrivateKey * +GNUNET_CRYPTO_rsa_decode_key (const char *buf, uint16_t len); /** @@ -688,7 +992,7 @@ struct GNUNET_CRYPTO_RsaPrivateKey *GNUNET_CRYPTO_rsa_key_create (void); * files does not exist, create a new key and write it to the * file. Caller must free return value. Note that this function * can not guarantee that another process might not be trying - * the same operation on the same file at the same time. + * the same operation on the same file at the same time. * If the contents of the file * are invalid the old file is deleted and a fresh key is * created. @@ -696,9 +1000,66 @@ struct GNUNET_CRYPTO_RsaPrivateKey *GNUNET_CRYPTO_rsa_key_create (void); * @param filename name of file to use for storage * @return new private key, NULL on error (for example, * permission denied) + * @deprecated use 'GNUNET_CRYPTO_rsa_key_create_start' instead + */ +struct GNUNET_CRYPTO_RsaPrivateKey * +GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename); + + +/** + * Handle to cancel private key generation. + */ +struct GNUNET_CRYPTO_RsaKeyGenerationContext; + + +/** + * Function called upon completion of 'GNUNET_CRYPTO_rsa_key_create_async'. + * + * @param cls closure + * @param pk NULL on error, otherwise the private key (which must be free'd by the callee) + * @param emsg NULL on success, otherwise an error message */ -struct GNUNET_CRYPTO_RsaPrivateKey - *GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename); +typedef void (*GNUNET_CRYPTO_RsaKeyCallback)(void *cls, + struct GNUNET_CRYPTO_RsaPrivateKey *pk, + const char *emsg); + + +/** + * Create a new private key by reading it from a file. If the files + * does not exist, create a new key and write it to the file. If the + * contents of the file are invalid the old file is deleted and a + * fresh key is created. + * + * @param filename name of file to use for storage + * @param cont function to call when done (or on errors) + * @param cont_cls closure for 'cont' + * @return handle to abort operation, NULL on fatal errors (cont will not be called if NULL is returned) + */ +struct GNUNET_CRYPTO_RsaKeyGenerationContext * +GNUNET_CRYPTO_rsa_key_create_start (const char *filename, + GNUNET_CRYPTO_RsaKeyCallback cont, + void *cont_cls); + + +/** + * Abort RSA key generation. + * + * @param gc key generation context to abort + */ +void +GNUNET_CRYPTO_rsa_key_create_stop (struct GNUNET_CRYPTO_RsaKeyGenerationContext *gc); + + +/** + * Setup a hostkey file for a peer given the name of the + * configuration file (!). This function is used so that + * at a later point code can be certain that reading a + * hostkey is fast (for example in time-dependent testcases). + * + * @param cfg_name name of the configuration file to use + */ +void +GNUNET_CRYPTO_rsa_setup_hostkey (const char *cfg_name); /** @@ -708,15 +1069,17 @@ struct GNUNET_CRYPTO_RsaPrivateKey * @param hc "random" input to PRNG * @return some private key purely dependent on input */ -struct GNUNET_CRYPTO_RsaPrivateKey - *GNUNET_CRYPTO_rsa_key_create_from_hash (const GNUNET_HashCode * hc); +struct GNUNET_CRYPTO_RsaPrivateKey * +GNUNET_CRYPTO_rsa_key_create_from_hash (const struct GNUNET_HashCode *hc); /** * Free memory occupied by the private key. - * @param hostkey pointer to the memory to free + * + * @param key pointer to the memory to free */ -void GNUNET_CRYPTO_rsa_key_free (struct GNUNET_CRYPTO_RsaPrivateKey *hostkey); +void +GNUNET_CRYPTO_rsa_key_free (struct GNUNET_CRYPTO_RsaPrivateKey *key); /** @@ -725,11 +1088,11 @@ void GNUNET_CRYPTO_rsa_key_free (struct GNUNET_CRYPTO_RsaPrivateKey *hostkey); * @param priv the private key * @param pub where to write the public key */ -void GNUNET_CRYPTO_rsa_key_get_public (const struct - GNUNET_CRYPTO_RsaPrivateKey *priv, - struct - GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded - *pub); +void +GNUNET_CRYPTO_rsa_key_get_public (const struct GNUNET_CRYPTO_RsaPrivateKey + *priv, + struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded + *pub); /** @@ -742,12 +1105,11 @@ void GNUNET_CRYPTO_rsa_key_get_public (const struct * @param target where to store the encrypted block * @return GNUNET_SYSERR on error, GNUNET_OK if ok */ -int GNUNET_CRYPTO_rsa_encrypt (const void *block, - size_t size, - const struct - GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded - *publicKey, - struct GNUNET_CRYPTO_RsaEncryptedData *target); +int +GNUNET_CRYPTO_rsa_encrypt (const void *block, size_t size, + const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded + *publicKey, + struct GNUNET_CRYPTO_RsaEncryptedData *target); /** @@ -759,11 +1121,10 @@ int GNUNET_CRYPTO_rsa_encrypt (const void *block, * @param max how many bytes of a result are expected? Must be exact. * @return the size of the decrypted block (that is, size) or -1 on error */ -ssize_t GNUNET_CRYPTO_rsa_decrypt (const struct GNUNET_CRYPTO_RsaPrivateKey *key, - const struct GNUNET_CRYPTO_RsaEncryptedData - *block, - void *result, - size_t max); +ssize_t +GNUNET_CRYPTO_rsa_decrypt (const struct GNUNET_CRYPTO_RsaPrivateKey *key, + const struct GNUNET_CRYPTO_RsaEncryptedData *block, + void *result, size_t max); /** @@ -774,10 +1135,10 @@ ssize_t GNUNET_CRYPTO_rsa_decrypt (const struct GNUNET_CRYPTO_RsaPrivateKey *key * @param sig where to write the signature * @return GNUNET_SYSERR on error, GNUNET_OK on success */ -int GNUNET_CRYPTO_rsa_sign (const struct GNUNET_CRYPTO_RsaPrivateKey *key, - const struct GNUNET_CRYPTO_RsaSignaturePurpose - *purpose, - struct GNUNET_CRYPTO_RsaSignature *sig); +int +GNUNET_CRYPTO_rsa_sign (const struct GNUNET_CRYPTO_RsaPrivateKey *key, + const struct GNUNET_CRYPTO_RsaSignaturePurpose *purpose, + struct GNUNET_CRYPTO_RsaSignature *sig); /** @@ -790,22 +1151,208 @@ int GNUNET_CRYPTO_rsa_sign (const struct GNUNET_CRYPTO_RsaPrivateKey *key, * @param publicKey public key of the signer * @return GNUNET_OK if ok, GNUNET_SYSERR if invalid */ -int GNUNET_CRYPTO_rsa_verify (uint32_t purpose, - const struct GNUNET_CRYPTO_RsaSignaturePurpose - *validate, - const struct GNUNET_CRYPTO_RsaSignature *sig, - const struct - GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded - *publicKey); +int +GNUNET_CRYPTO_rsa_verify (uint32_t purpose, + const struct GNUNET_CRYPTO_RsaSignaturePurpose + *validate, + const struct GNUNET_CRYPTO_RsaSignature *sig, + const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded + *publicKey); + + + +/** + * Function called upon completion of 'GNUNET_CRYPTO_ecc_key_create_async'. + * + * @param cls closure + * @param pk NULL on error, otherwise the private key (which must be free'd by the callee) + * @param emsg NULL on success, otherwise an error message + */ +typedef void (*GNUNET_CRYPTO_EccKeyCallback)(void *cls, + struct GNUNET_CRYPTO_EccPrivateKey *pk, + const char *emsg); + + +/** + * Free memory occupied by ECC key + * + * @param privatekey pointer to the memory to free + */ +void +GNUNET_CRYPTO_ecc_key_free (struct GNUNET_CRYPTO_EccPrivateKey *privatekey); + + +/** + * Extract the public key for the given private key. + * + * @param priv the private key + * @param pub where to write the public key + */ +void +GNUNET_CRYPTO_ecc_key_get_public (const struct GNUNET_CRYPTO_EccPrivateKey *priv, + struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded *pub); + +/** + * Convert a public key to a string. + * + * @param pub key to convert + * @return string representing 'pub' + */ +char * +GNUNET_CRYPTO_ecc_public_key_to_string (struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded *pub); + + +/** + * Convert a string representing a public key to a public key. + * + * @param enc encoded public key + * @param enclen number of bytes in enc (without 0-terminator) + * @param pub where to store the public key + * @return GNUNET_OK on success + */ +int +GNUNET_CRYPTO_ecc_public_key_from_string (const char *enc, + size_t enclen, + struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded *pub); + + +/** + * Encode the private key in a format suitable for + * storing it into a file. + * + * @param key key to encode + * @return encoding of the private key. + * The first 4 bytes give the size of the array, as usual. + */ +struct GNUNET_CRYPTO_EccPrivateKeyBinaryEncoded * +GNUNET_CRYPTO_ecc_encode_key (const struct GNUNET_CRYPTO_EccPrivateKey *key); + + +/** + * Decode the private key from the file-format back + * to the "normal", internal format. + * + * @param buf the buffer where the private key data is stored + * @param len the length of the data in 'buffer' + * @return NULL on error + */ +struct GNUNET_CRYPTO_EccPrivateKey * +GNUNET_CRYPTO_ecc_decode_key (const char *buf, + size_t len); + + +/** + * Create a new private key by reading it from a file. If the + * files does not exist, create a new key and write it to the + * file. Caller must free return value. Note that this function + * can not guarantee that another process might not be trying + * the same operation on the same file at the same time. + * If the contents of the file + * are invalid the old file is deleted and a fresh key is + * created. + * + * @return new private key, NULL on error (for example, + * permission denied) + */ +struct GNUNET_CRYPTO_EccPrivateKey * +GNUNET_CRYPTO_ecc_key_create_from_file (const char *filename); + + +/** + * Handle to cancel private key generation and state for the + * key generation operation. + */ +struct GNUNET_CRYPTO_EccKeyGenerationContext; + + +/** + * Create a new private key by reading it from a file. If the files + * does not exist, create a new key and write it to the file. If the + * contents of the file are invalid the old file is deleted and a + * fresh key is created. + * + * @param filename name of file to use for storage + * @param cont function to call when done (or on errors) + * @param cont_cls closure for 'cont' + * @return handle to abort operation, NULL on fatal errors (cont will not be called if NULL is returned) + */ +struct GNUNET_CRYPTO_EccKeyGenerationContext * +GNUNET_CRYPTO_ecc_key_create_start (const char *filename, + GNUNET_CRYPTO_EccKeyCallback cont, + void *cont_cls); + + +/** + * Abort ECC key generation. + * + * @param gc key generation context to abort + */ +void +GNUNET_CRYPTO_ecc_key_create_stop (struct GNUNET_CRYPTO_EccKeyGenerationContext *gc); + +/** + * Setup a hostkey file for a peer given the name of the + * configuration file (!). This function is used so that + * at a later point code can be certain that reading a + * hostkey is fast (for example in time-dependent testcases). + * + * @param cfg_name name of the configuration file to use + */ +void +GNUNET_CRYPTO_ecc_setup_hostkey (const char *cfg_name); + + +/** + * Sign a given block. + * + * @param key private key to use for the signing + * @param purpose what to sign (size, purpose) + * @param sig where to write the signature + * @return GNUNET_SYSERR on error, GNUNET_OK on success + */ +int +GNUNET_CRYPTO_ecc_sign (const struct GNUNET_CRYPTO_EccPrivateKey *key, + const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, + struct GNUNET_CRYPTO_EccSignature *sig); +/** + * Verify signature. + * + * @param purpose what is the purpose that the signature should have? + * @param validate block to validate (size, purpose, data) + * @param sig signature that is being validated + * @param publicKey public key of the signer + * @returns GNUNET_OK if ok, GNUNET_SYSERR if invalid + */ +int +GNUNET_CRYPTO_ecc_verify (uint32_t purpose, + const struct GNUNET_CRYPTO_EccSignaturePurpose + *validate, + const struct GNUNET_CRYPTO_EccSignature *sig, + const struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded + *publicKey); + /** * This function should only be called in testcases * where strong entropy gathering is not desired - * (for example, for hostkey generation). + * (for example, for hostkey generation). + */ +void +GNUNET_CRYPTO_random_disable_entropy_gathering (void); + + +/** + * Check if we are using weak random number generation. + * + * @return GNUNET_YES if weak number generation is on + * (thus will return YES if 'GNUNET_CRYPTO_random_disable_entropy_gathering' + * was called previously). */ -void GNUNET_CRYPTO_random_disable_entropy_gathering (void); +int +GNUNET_CRYPTO_random_is_weak (void); + #if 0 /* keep Emacsens' auto-indent happy */ {