You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
148 lines
4.5 KiB
148 lines
4.5 KiB
#ifndef _CC20_H
|
|
#define _CC20_H
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#define restrict __restrict__
|
|
#endif
|
|
|
|
#include <stdint.h>
|
|
#include <stddef.h>
|
|
|
|
/// CC20 C interface versioning macro.
|
|
/// Most significant 8 bits is major, then next 8 is minor, then bugfix, then revision.
|
|
/// The componants should never exceed 255, or that is undefined behaviour. They should also be unsigned int (uint32_t), or that is undefined behaviour.
|
|
/// This macro is not intended to be used.
|
|
#define _CC20_VERSION(ma,mi,bu,r) (((ma) << 24) | ((mi) << 16) | ((bu) << 8) | (r))
|
|
|
|
/// C interface API version
|
|
#define CC20_C_API_VERSION 0
|
|
/// The last library version as unsigned int.
|
|
#define CC20_MIN_LIBRARY_VERSION _CC20_VERSION(1u, 2u, 0, 0)
|
|
|
|
#define CC20_KEY_SIZE 32
|
|
#define CC20_IV_SIZE 12
|
|
|
|
enum cc20_mode {
|
|
/// Encrypt the data written to this stream
|
|
CC20_ENCRYPT,
|
|
/// Decrypt the data written to this stream
|
|
CC20_DECRYPT,
|
|
};
|
|
|
|
/// Result from a `cc20_` internal operation.
|
|
typedef enum cc20_error {
|
|
/// An internal fatal error
|
|
CC20_ERR_PANIC = -1,
|
|
/// Operation succeeded
|
|
CC20_ERR_NONE = 0,
|
|
|
|
/// If a `FILE*` stream is used that is invalid or `NULL`.
|
|
CC20_ERR_INVALID_FILE,
|
|
/// If a pointer is `NULL` that should not be
|
|
CC20_ERR_NULL_PTR,
|
|
/// An underlying `libssl` call fails
|
|
CC20_ERR_SSL,
|
|
/// There is a generic I/O failure
|
|
CC20_ERR_IO
|
|
} cc20_result_t;
|
|
|
|
#define CC20_OK(v) ((v)==CC20_ERR_NONE)
|
|
#define CC20_ERR(v) ((v)!=CC20_ERR_NONE)
|
|
|
|
/// A chacha20_poly1305 key
|
|
typedef uint8_t cc20_key_t[CC20_KEY_SIZE];
|
|
/// A chacha20_poly1305 IV
|
|
typedef uint8_t cc20_iv_t[CC20_IV_SIZE];
|
|
|
|
/// Metadata used to construct an instance of `cc20_sink_t`.
|
|
typedef struct cc20_metadata {
|
|
/// A valid, non-NULL, stream that the sink will write the transformed data to.
|
|
FILE* backing;
|
|
/// The key used for the cipher
|
|
cc20_key_t key;
|
|
/// The iv used to initialise the cipher.
|
|
cc20_iv_t iv;
|
|
/// The transformation mode
|
|
///
|
|
/// *MUST* be a valid `enum cc20_mode` disctiminant or UB.
|
|
enum cc20_mode mode;
|
|
} cc20_meta_t;
|
|
|
|
/// Configuration for a wrapper `FILE*` stream over a `cc20_sink_t`.
|
|
struct cc20_wrap_cfg {
|
|
/// Keep the backing (`cc20_meta_t.backing`) stream alive (do not `fclose()` it) when the wrapper is closed.
|
|
/// # Default
|
|
/// * false (0)
|
|
int keep_alive;
|
|
};
|
|
|
|
/// An opaque type containing the cipher transform and the backing stream.
|
|
typedef struct cc20_sink cc20_sink_t;
|
|
|
|
// Functions //
|
|
|
|
/// Parameters tagged with this must be valid, non-NULL and non-aliased; but can point to uninitialised memory for this type.
|
|
/// They are guaranteed to be written to with a valid value if the function succeeds. If it fails, it is unspecified whether it will be written to.
|
|
//TODO: Attribute non-NULL how?
|
|
#define _cc20_OUT *restrict
|
|
|
|
/// Generate a new securely random key and/or iv.
|
|
///
|
|
/// # Possible errors
|
|
/// * `CC20_ERR_PANIC` - If the RNG fails.
|
|
cc20_result_t cc20_keygen(cc20_key_t* restrict key,
|
|
cc20_iv_t* restrict iv);
|
|
|
|
/// Write these parameters to `output` metadata.
|
|
/// * `key` and `iv` can be NULL, if one or both are, the field(s) will be initialised to secure random data in the `output` metadata (same as `cc20_keygen`.
|
|
/// * `file` must be non-NULL and valid.
|
|
/// # Possible errors
|
|
/// * `CC20_ERR_INVALID_FILE` - if `file` is NULL.
|
|
/// * `CC20_ERR_NULL_PTR` - if `output` is NULL. (see `_cc20_OUT`.)
|
|
/// ## Undefined behaviour
|
|
/// If `mode` is not a valid distriminant of `enum cc20_mdoe`.
|
|
cc20_result_t cc20_gen_meta(FILE* file,
|
|
const cc20_key_t* key,
|
|
const cc20_iv_t* iv,
|
|
enum cc20_mode mode,
|
|
struct cc20_metadata _cc20_OUT output);
|
|
|
|
/// Create a sink from the specified metadata and write it to `output`.
|
|
///
|
|
/// # Possible errors
|
|
/// * `CC20_ERR_NULL_PTR` - If `meta` or `output` is NULL.
|
|
cc20_result_t cc20_gen_sink(const struct cc20_metadata* meta,
|
|
cc20_sink_t* _cc20_OUT output);
|
|
|
|
//TODO: Rework this entire API interface. Its clunky.
|
|
//TODO: Document the rest
|
|
cc20_result_t cc20_gen_sink_full(FILE* file,
|
|
const cc20_key_t* key,
|
|
const cc20_iv_t* iv,
|
|
enum cc20_mode mode,
|
|
cc20_sink_t* _cc20_OUT output);
|
|
|
|
cc20_result_t cc20_wrap_full(FILE* file,
|
|
const cc20_key_t* key,
|
|
const cc20_iv_t* iv,
|
|
enum cc20_mode mode,
|
|
FILE* _cc20_OUT output);
|
|
|
|
cc20_result_t cc20_gen(const struct cc20_metadata* meta,
|
|
FILE* _cc20_OUT output);
|
|
|
|
cc20_result_t cc20_close_sink(cc20_sink_t* sink,
|
|
struct cc20_metadata* restrict meta);
|
|
|
|
cc20_result_t cc20_write(const void* ptr, size_t * restrict bytes, cc20_sink_t* restrict sink);
|
|
|
|
FILE* cc20_wrap_sink(cc20_sink_t* sink, const struct cc20_wrap_cfg* cfg);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#undef restrict
|
|
#endif
|
|
|
|
#endif /* _CC20_H */
|