From 51e3cec60df404cf9689ab80dae33176306ca991 Mon Sep 17 00:00:00 2001 From: "git@daemon.de" Date: Wed, 19 Feb 2014 20:39:19 +0100 Subject: [PATCH] api doc updated --- include/pcp/buffer.h | 2 +- include/pcp/crypto.h | 207 ++++++++++++++++++++++++++++++++++++++++ include/pcp/defines.h | 29 +++++- include/pcp/key.h | 29 ++++-- include/pcp/mgmt.h | 2 +- include/pcp/pcpstream.h | 6 +- 6 files changed, 261 insertions(+), 14 deletions(-) diff --git a/include/pcp/buffer.h b/include/pcp/buffer.h index 0332312..63153f6 100644 --- a/include/pcp/buffer.h +++ b/include/pcp/buffer.h @@ -29,7 +29,7 @@ #include "defines.h" /** - * \defgroup Buffer Buffer, a flexible buffer management class. + * \defgroup Buffer BUFFER * @{ Flexible buffer management, idea from openssh/buffer.c. diff --git a/include/pcp/crypto.h b/include/pcp/crypto.h index 64c0a79..36e35e9 100644 --- a/include/pcp/crypto.h +++ b/include/pcp/crypto.h @@ -36,6 +36,85 @@ #include "ed.h" #include "pcpstream.h" +/** + \defgroup CRYPTO CRYPTO + @{ + + Functions for symmetrical or asymmetrical encryption using NaCL. + + \section intro Introduction + + Encryption is done 32k blockwise using an ephemeral key. + + If using asymmetrical encryption the ephemeral key is encrypted + asymmetrically using Curve25519 for all recipients and added to + the output. + + If sign+crypt is requested, a hash of the clear content plus + the recipient list will be made and signed. That signature + will be encrypted using the ephemeral key as well and appended + to the output. + + For each encryption cycle (per block) a unique nonce will be + used. + + \section format Encrypted Output Format + + Encrypted output will always written as binary files. No armoring + supported yet. The encryption process works as this: + + - generate a random symetric 32 byte key B + - encrypt it asymetrically for each recipient using a unique nonce (B) + - encrypt the input file 32k blockwise using the symetric key + + Symmetric encryption works the very same with the recipient stuff + left out. + + Formal format description, asymmetric encrypted files: + + +---------------------------------------------------------+ + | Field Size Description | + +-------------+--------+----------------------------------+ + | Type | 1 | Filetype, 5=ASYM, 23=SYM | + +-------------|--------|----------------------------------+ + | Len R | 4 | Number of recipients (*) | + +-------------|--------|----------------------------------+ + | Recipients | R*72 | C(recipient)|C(recipient)... (*) | + +-------------|--------|----------------------------------+ + | Encrypted | ~ | The actual encrypted data | + +-------------|--------|----------------------------------+ + + The following will be Left out when doing symetric encryption. + + Recipient field format: + + +---------------------------------------------------------+ + | Field Size Description | + +-------------+--------+----------------------------------+ + | Nonce | 24 | Random Nonce, one per R | + +-------------|--------|----------------------------------+ + | Cipher | 48 | S encrypted with PK or R | + +-------------|--------|----------------------------------+ + + R is calculated using public key encryption using the senders + secret key, the recipients public key and a random nonce. + + Pseudocode: + + @code + R = foreach P: N | crypto_box(S, N, P, SK) + L = len(R) + T = 5 + write (T | L | R) + foreach I: write (N | crypto_secret_box(I, N, S)) + @endcode + + where P is the public key of a recipient, SK is the senders + secret key, R is the recipient list, L is the number of recipients, + T is the filetype header, I is a block of input with a size + of 32k, N is a nonce (new per block) and S the symmetric key. +*/ + size_t pcp_sodium_box(unsigned char **cipher, unsigned char *cleartext, size_t clearsize, @@ -47,21 +126,149 @@ int pcp_sodium_verify_box(unsigned char **cleartext, unsigned char* message, size_t messagesize, unsigned char *nonce, unsigned char *secret, unsigned char *pub); +/** Asymmetrically encrypt a message. + + This function is used internally and normally a user doesn't + need to use it. However, from time to time there maybe the + requirement to work with raw NaCL crypto_box() output. This + function adds the neccessary padding and it uses PCP key structures. + + \param[in] secret The secret key structure from the sender. + + \param[in] pub The public key structure from the recipient. + + \param[in] message The clear unencrypted message. + + \param[in] messagesize The size in bytes of the message. + + \param[out] csize A pointer which will be set to the size of the encrypted result if successful. + + \return Returns an allocated unsigned char array of the size csize which contains the encrypted result. + In case of an error, it returns NULL sets csize to 0. Use fatals_ifany() to check for errors. +*/ unsigned char *pcp_box_encrypt(pcp_key_t *secret, pcp_pubkey_t *pub, unsigned char *message, size_t messagesize, size_t *csize); +/** Asymmetrically decrypt a message. + + This function is used internally and normally a user doesn't + need to use it. However, from time to time there maybe the + requirement to work with raw NaCL crypto_box() output. This + function adds the neccessary padding and it uses PCP key structures. + + \param[in] secret The secret key structure from the sender. + + \param[in] pub The public key structure from the recipient. + + \param[in] cipher The encrypted message. + + \param[in] ciphersize The size in bytes of the encrypted message. + + \param[out] dsize A pointer which will be set to the size of the decrypted result if successful. + + \return Returns an allocated unsigned char array of the size csize which contains the encrypted result. + In case of an error, it returns NULL sets csize to 0. Use fatals_ifany() to check for errors. +*/ +unsigne unsigned char *pcp_box_decrypt(pcp_key_t *secret, pcp_pubkey_t *pub, unsigned char *cipher, size_t ciphersize, size_t *dsize); + +/** Asymmetrically encrypt a file or a buffer stream. + + This function encrypts a stream 32k-blockwise for + a number of recipients. + + Calls pcp_encrypt_stream_sym() after assembling the encrypted recipient list. + + \param[in] in Stream to read the data to encrypt from. + + \param[out] out Stream to write encrypted result to. + + \param[in] s Secret key structure of the sender. + + \param[in] p Public key hash containing a list of the recipients. + + \param signcrypt Flag to indicate sign+crypt. If 1 it adds a signature, otherwise not. + + \return Returns the size of the output written to the output stream or 0 in case of errors. +*/ size_t pcp_encrypt_stream(Pcpstream *in, Pcpstream* out, pcp_key_t *s, pcp_pubkey_t *p, int signcrypt); + +/** Symmetrically encrypt a file or a buffer stream. + + This function encrypts a stream 32k-blockwise using + a given ephemeral key. Usually compute this key using the pcp_scrypt() + function. + + Uses crypto_secret_box() for each 32k-block with a random nonce for each. + + \param[in] in Stream to read the data to encrypt from. + + \param[out] out Stream to write encrypted result to. + + \param[in] symkey Ephemeral key to use for encryption. + + \param[in] havehead Flag to indicate if the file header has already been written. + Set to 0 if you call this function directly in order to do symmetrical encryption. + + \param recsign Recipient list, set this to NULL if you call this function directly. + + \return Returns the size of the output written to the output stream or 0 in case of errors. +*/ size_t pcp_encrypt_stream_sym(Pcpstream *in, Pcpstream* out, unsigned char *symkey, int havehead, pcp_rec_t *recsign); + +/** Asymmetrically decrypt a file or a buffer stream. + + This function decrypts a stream 32k+16-blockwise for + a number of recipients. + + Calls pcp_decrypt_stream_sym() after assembling the encrypted recipient list. + + FIXME: should return the pcp_rec_t structure upon successfull verification somehow. + + \param[in] in Stream to read the data to decrypt from. + + \param[out] out Stream to write decrypted result to. + + \param[in] s Secret key structure of the recipient. + + \param[in] symkey Ephemeral key for symmetric decryption. Set to NULL if you call this function directly. + + \param verify Flag to indicate sign+crypt. If 1 it tries to verify a signature, otherwise not. + + \return Returns the size of the output written to the output stream or 0 in case of errors. +*/ size_t pcp_decrypt_stream(Pcpstream *in, Pcpstream* out, pcp_key_t *s, unsigned char *symkey, int verify); + + +/** Symmetrically decrypt a file or a buffer stream. + + This function decrypts a stream 32k+16-blockwise using + a given ephemeral key. Usually compute this key using the pcp_scrypt() + function. If not called directly, the key have been extracted from + the recipient list. + + Uses crypto_secret_box_open() for each 32k+16-block with a random nonce for each. + + \param[in] in Stream to read the data to decrypt from. + + \param[out] out Stream to write decrypted result to. + + \param[in] symkey Ephemeral key to use for decryption. + + \param recverify Flag to indicate sign+crypt. If 1 it tries to verify a signature, otherwise not. + + \return Returns the size of the output written to the output stream or 0 in case of errors. +*/ size_t pcp_decrypt_stream_sym(Pcpstream *in, Pcpstream* out, unsigned char *symkey, pcp_rec_t *recverify); pcp_rec_t *pcp_rec_new(unsigned char *cipher, size_t clen, pcp_key_t *secret, pcp_pubkey_t *pub); void pcp_rec_free(pcp_rec_t *r); #endif /* _HAVE_PCP_CRYPTO_H */ + +/**@}*/ diff --git a/include/pcp/defines.h b/include/pcp/defines.h index f09ce7c..d61f200 100644 --- a/include/pcp/defines.h +++ b/include/pcp/defines.h @@ -23,6 +23,33 @@ #ifndef _DEFINES_H #define _DEFINES_H + +/** \mainpage + + \section intro_sec Introduction + + This is the API documentation of libpcp, the library behind + Pretty Curved Privacy (pcp). The library can be used independently + of pcp to manage keys and to encrypt or sign files or buffers. + + For most actual crypto related things, libpcp uses libsodium, + the portable NaCL library. + + \section sample_sec Sample usage + + Example use of the libpcp library: + + \include tests/sample.c + + To compile the example, use the following commands: + + @code + g++ -c sample.o `pkg-config --cflags libpcp1` + g++ sample.o `pkg-config --libs libpcp1` -o sample + @endcode + */ + + #include "config.h" typedef unsigned char byte; /* Single unsigned byte = 8 bits */ @@ -93,7 +120,7 @@ typedef unsigned int qbyte; /* Quad byte = 32 bits */ #define PCP_RFC_CIPHER 0x21 /* curve25519+ed25519+poly1305+salsa20+blake2 */ /** - * \defgroup FATALS global variables and functions for error handling. + * \defgroup FATALS FATALS * @{ A couple of functions to catch errors and display them. diff --git a/include/pcp/key.h b/include/pcp/key.h index 258644e..ea5e0b7 100644 --- a/include/pcp/key.h +++ b/include/pcp/key.h @@ -42,9 +42,11 @@ /** - * \defgroup PCPKEY PCP public and secret key functions + * \defgroup KEYS KEYS * @{ + PCP public and secret key functions. + Functions to generate PCP keypairs, de- and encrypt them and various related helpers. */ @@ -151,18 +153,24 @@ struct _pbp_pubkey_t { typedef struct _pbp_pubkey_t pbp_pubkey_t; -/* - encrypted recipient list, required for crypt+sign - contains the encrypted recipients and the secret - key required for signing the message+recipients. +/** \struct _pcp_rec_t + + Encrypted recipient list. + + Encrypted recipient list, required for crypt+sign + contains the encrypted recipients and the secret + key required for signing the message+recipients. + + Used internally only. */ struct _pcp_rec_t { - size_t ciphersize; - byte *cipher; - pcp_key_t *secret; - pcp_pubkey_t *pub; + size_t ciphersize; /**< the size of the encrypted recipient list */ + byte *cipher; /**< contains the whole encrypted recipient list */ + pcp_key_t *secret; /**< the secret key of the recipient for signing */ + pcp_pubkey_t *pub; /**< if verification were ok, contains the public key of the signer */ }; +/** Typedef for public keys */ typedef struct _pcp_rec_t pcp_rec_t; #define PCP_RAW_KEYSIZE sizeof(pcp_key_t) - sizeof(UT_hash_handle) @@ -420,6 +428,9 @@ int pcp_sanitycheck_pub(pcp_pubkey_t *key); */ int pcp_sanitycheck_key(pcp_key_t *key); +void pcp_dumpkey(pcp_key_t *k); +void pcp_dumppubkey(pcp_pubkey_t *k); + #endif /* _HAVE_PCP_KEYPAIR_H */ diff --git a/include/pcp/mgmt.h b/include/pcp/mgmt.h index fd5849f..78a1f09 100644 --- a/include/pcp/mgmt.h +++ b/include/pcp/mgmt.h @@ -44,7 +44,7 @@ /** - * \defgroup PubKeyExport Key export functions + * \defgroup PubKeyExport KEYEXPORT * @{ Functions to export and import keys in various formats. diff --git a/include/pcp/pcpstream.h b/include/pcp/pcpstream.h index 50bc09e..ff11b44 100644 --- a/include/pcp/pcpstream.h +++ b/include/pcp/pcpstream.h @@ -30,8 +30,10 @@ #include "buffer.h" /** - * \defgroup Pcpstream I/O wrapper for files or buffers + * \defgroup Pcpstream PCPSTREAMS * @{ + + I/O wrapper for files or buffers. Simple wrapper around FILE streams or Buffers, depending how the user initialized them. The Pcpstream object behaves @@ -173,7 +175,7 @@ size_t ps_tell(Pcpstream *stream); */ Buffer *ps_buffer(Pcpstream *stream); -/** Close the stream and frees allocated memory +/** Close the stream and frees allocated memory. If the backend of the stream was a FILE stream, close it, unless it is stdin, stdout or stderr.