2017-04-05 20:56:22 +00:00
|
|
|
//==============================================================================
|
|
|
|
// This file is part of Master Password.
|
|
|
|
// Copyright (c) 2011-2017, Maarten Billemont.
|
2014-12-20 19:30:34 +00:00
|
|
|
//
|
2017-04-05 20:56:22 +00:00
|
|
|
// Master Password is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
// (at your option) any later version.
|
2014-12-20 19:30:34 +00:00
|
|
|
//
|
2017-04-05 20:56:22 +00:00
|
|
|
// Master Password is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU General Public License for more details.
|
2014-12-20 19:30:34 +00:00
|
|
|
//
|
2017-04-05 20:56:22 +00:00
|
|
|
// You can find a copy of the GNU General Public License in the
|
|
|
|
// LICENSE file. Alternatively, see <http://www.gnu.org/licenses/>.
|
|
|
|
//==============================================================================
|
2014-12-20 19:30:34 +00:00
|
|
|
|
2017-07-16 01:13:49 +00:00
|
|
|
#ifndef _MPW_UTIL_H
|
|
|
|
#define _MPW_UTIL_H
|
2015-01-20 04:21:10 +00:00
|
|
|
|
2017-07-28 13:50:26 +00:00
|
|
|
#include <stdio.h>
|
2017-08-03 05:07:19 +00:00
|
|
|
#include <stdarg.h>
|
2017-07-28 13:50:26 +00:00
|
|
|
|
|
|
|
#include "mpw-types.h"
|
|
|
|
|
2014-12-22 04:45:19 +00:00
|
|
|
//// Logging.
|
|
|
|
|
2016-01-04 19:52:05 +00:00
|
|
|
#ifndef trc
|
2017-04-08 18:25:54 +00:00
|
|
|
extern int mpw_verbosity;
|
2017-08-03 05:07:19 +00:00
|
|
|
#define trc_level 3
|
2017-08-04 13:36:03 +00:00
|
|
|
/** Logging internal state. */
|
2017-08-03 05:07:19 +00:00
|
|
|
#define trc(...) ({ \
|
|
|
|
if (mpw_verbosity >= 3) \
|
|
|
|
fprintf( stderr, __VA_ARGS__ ); })
|
2016-01-04 19:52:05 +00:00
|
|
|
#endif
|
|
|
|
#ifndef dbg
|
2017-08-03 05:07:19 +00:00
|
|
|
#define dbg_level 2
|
2017-08-04 13:36:03 +00:00
|
|
|
/** Logging state and events interesting when investigating issues. */
|
2017-08-03 05:07:19 +00:00
|
|
|
#define dbg(...) ({ \
|
|
|
|
if (mpw_verbosity >= 2) \
|
|
|
|
fprintf( stderr, __VA_ARGS__ ); })
|
2016-01-04 19:52:05 +00:00
|
|
|
#endif
|
|
|
|
#ifndef inf
|
2017-08-03 05:07:19 +00:00
|
|
|
#define inf_level 1
|
2017-08-04 13:36:03 +00:00
|
|
|
/** User messages. */
|
2017-08-03 05:07:19 +00:00
|
|
|
#define inf(...) ({ \
|
|
|
|
if (mpw_verbosity >= 1) \
|
|
|
|
fprintf( stderr, __VA_ARGS__ ); })
|
2016-01-04 19:52:05 +00:00
|
|
|
#endif
|
|
|
|
#ifndef wrn
|
2017-08-03 05:07:19 +00:00
|
|
|
#define wrn_level 0
|
2017-08-04 13:36:03 +00:00
|
|
|
/** Recoverable issues and user suggestions. */
|
2017-08-03 05:07:19 +00:00
|
|
|
#define wrn(...) ({ \
|
|
|
|
if (mpw_verbosity >= 0) \
|
|
|
|
fprintf( stderr, __VA_ARGS__ ); })
|
2016-01-04 19:52:05 +00:00
|
|
|
#endif
|
|
|
|
#ifndef err
|
2017-08-03 05:07:19 +00:00
|
|
|
#define err_level -1
|
2017-08-04 13:36:03 +00:00
|
|
|
/** Unrecoverable issues. */
|
2017-08-03 05:07:19 +00:00
|
|
|
#define err(...) ({ \
|
|
|
|
if (mpw_verbosity >= -1) \
|
|
|
|
fprintf( stderr, __VA_ARGS__ ); })
|
2015-02-02 19:47:16 +00:00
|
|
|
#endif
|
2014-12-22 04:45:19 +00:00
|
|
|
#ifndef ftl
|
2017-08-03 05:07:19 +00:00
|
|
|
#define ftl_level -2
|
2017-08-04 13:36:03 +00:00
|
|
|
/** Issues that lead to abortion. */
|
2017-08-03 05:07:19 +00:00
|
|
|
#define ftl(...) ({ \
|
|
|
|
if (mpw_verbosity >= -2) \
|
|
|
|
fprintf( stderr, __VA_ARGS__ ); })
|
2014-12-22 04:45:19 +00:00
|
|
|
#endif
|
2017-08-03 05:07:19 +00:00
|
|
|
|
2017-07-23 01:38:53 +00:00
|
|
|
#ifndef min
|
|
|
|
#define min(a, b) ({ \
|
|
|
|
__typeof__ (a) _a = (a); \
|
|
|
|
__typeof__ (b) _b = (b); \
|
|
|
|
_a < _b ? _a : _b; })
|
|
|
|
#endif
|
|
|
|
#ifndef max
|
|
|
|
#define max(a, b) ({ \
|
|
|
|
__typeof__ (a) _a = (a); \
|
|
|
|
__typeof__ (b) _b = (b); \
|
|
|
|
_a > _b ? _a : _b; })
|
|
|
|
#endif
|
2017-08-04 13:36:03 +00:00
|
|
|
#ifndef ERR
|
|
|
|
#define ERR -1
|
|
|
|
#endif
|
2017-08-08 04:00:14 +00:00
|
|
|
#ifndef stringify
|
|
|
|
#define stringify(s) #s
|
|
|
|
#endif
|
|
|
|
#ifndef stringify_def
|
|
|
|
#define stringify_def(s) stringify(s)
|
|
|
|
#endif
|
2014-12-22 04:45:19 +00:00
|
|
|
|
2014-12-20 19:30:34 +00:00
|
|
|
//// Buffers and memory.
|
|
|
|
|
2017-08-27 11:46:34 +00:00
|
|
|
/** Write a number to a byte buffer using mpw's endianness (big/network endian). */
|
|
|
|
void mpw_uint16(const uint16_t number, uint8_t buf[2]);
|
|
|
|
void mpw_uint32(const uint32_t number, uint8_t buf[4]);
|
|
|
|
void mpw_uint64(const uint64_t number, uint8_t buf[8]);
|
|
|
|
|
2017-08-01 20:50:50 +00:00
|
|
|
/** Allocate a new array of _type, assign its element count to _count if not NULL and populate it with the varargs. */
|
2016-11-03 14:04:18 +00:00
|
|
|
#define mpw_alloc_array(_count, _type, ...) ({ \
|
2015-02-09 18:02:22 +00:00
|
|
|
_type stackElements[] = { __VA_ARGS__ }; \
|
2017-08-01 20:50:50 +00:00
|
|
|
if (_count) \
|
|
|
|
*_count = sizeof( stackElements ) / sizeof( _type ); \
|
2015-02-07 16:10:59 +00:00
|
|
|
_type *allocElements = malloc( sizeof( stackElements ) ); \
|
|
|
|
memcpy( allocElements, stackElements, sizeof( stackElements ) ); \
|
|
|
|
allocElements; \
|
|
|
|
})
|
|
|
|
|
2014-12-20 19:30:34 +00:00
|
|
|
/** Push a buffer onto a buffer. reallocs the given buffer and appends the given buffer. */
|
2017-07-16 01:13:49 +00:00
|
|
|
bool mpw_push_buf(
|
2017-08-23 04:01:23 +00:00
|
|
|
uint8_t ** buffer, size_t *bufferSize, const void *pushBuffer, const size_t pushSize);
|
2014-12-20 19:30:34 +00:00
|
|
|
/** Push a string onto a buffer. reallocs the given buffer and appends the given string. */
|
2017-07-16 01:13:49 +00:00
|
|
|
bool mpw_push_string(
|
2017-08-23 04:01:23 +00:00
|
|
|
uint8_t **buffer, size_t *bufferSize, const char *pushString);
|
2017-08-03 05:07:19 +00:00
|
|
|
/** Push a string onto another string. reallocs the target string and appends the source string. */
|
|
|
|
bool mpw_string_push(
|
2017-08-23 04:01:23 +00:00
|
|
|
char **string, const char *pushString);
|
2017-08-03 05:07:19 +00:00
|
|
|
bool mpw_string_pushf(
|
2017-08-23 04:01:23 +00:00
|
|
|
char **string, const char *pushFormat, ...);
|
2014-12-20 19:30:34 +00:00
|
|
|
/** Push an integer onto a buffer. reallocs the given buffer and appends the given integer. */
|
2017-07-16 01:13:49 +00:00
|
|
|
bool mpw_push_int(
|
2017-08-23 04:01:23 +00:00
|
|
|
uint8_t **buffer, size_t *bufferSize, const uint32_t pushInt);
|
2017-08-05 23:04:42 +00:00
|
|
|
/** Reallocate the given buffer from the given size by adding the delta size.
|
|
|
|
* On success, the buffer size pointer will be updated to the buffer's new size
|
|
|
|
* and the buffer pointer may be updated to a new memory address.
|
|
|
|
* On failure, the buffer and pointers will remain unaffected.
|
|
|
|
* @param buffer A pointer to the buffer to reallocate.
|
|
|
|
* @param bufferSize A pointer to the buffer's actual size.
|
|
|
|
* @param deltaSize The amount to increase the buffer's size by.
|
|
|
|
* @return true if successful, false if reallocation failed.
|
|
|
|
*/
|
2017-08-06 22:56:37 +00:00
|
|
|
#define mpw_realloc(buffer, bufferSize, deltaSize) \
|
2017-08-23 04:01:23 +00:00
|
|
|
({ typeof(buffer) _b = buffer; const void *__b = *_b; __mpw_realloc( (const void **)_b, bufferSize, deltaSize ); })
|
|
|
|
bool __mpw_realloc(const void **buffer, size_t *bufferSize, const size_t deltaSize);
|
|
|
|
/** Free a buffer after zero'ing its contents, then set the reference to NULL. */
|
|
|
|
#define mpw_free(buffer, bufferSize) \
|
2017-08-23 04:53:14 +00:00
|
|
|
({ typeof(buffer) _b = buffer; const void *__b = *_b; __mpw_free( (const void **)_b, bufferSize ); })
|
2017-08-23 04:01:23 +00:00
|
|
|
bool __mpw_free(
|
|
|
|
const void **buffer, const size_t bufferSize);
|
|
|
|
/** Free a string after zero'ing its contents, then set the reference to NULL. */
|
|
|
|
#define mpw_free_string(string) \
|
2017-08-23 04:53:14 +00:00
|
|
|
({ typeof(string) _s = string; const char *__s = *_s; __mpw_free_string( (const char **)_s ); })
|
2017-08-23 04:01:23 +00:00
|
|
|
bool __mpw_free_string(
|
|
|
|
const char **string);
|
|
|
|
/** Free strings after zero'ing their contents, then set the references to NULL. Terminate the va_list with NULL. */
|
|
|
|
#define mpw_free_strings(strings, ...) \
|
2017-08-23 04:53:14 +00:00
|
|
|
({ typeof(strings) _s = strings; const char *__s = *_s; __mpw_free_strings( (const char **)_s, __VA_ARGS__ ); })
|
2017-08-23 04:01:23 +00:00
|
|
|
bool __mpw_free_strings(
|
|
|
|
const char **strings, ...);
|
2014-12-20 19:30:34 +00:00
|
|
|
|
|
|
|
//// Cryptographic functions.
|
|
|
|
|
2017-08-05 21:33:45 +00:00
|
|
|
/** Derive a key from the given secret and salt using the scrypt KDF.
|
|
|
|
* @return A new keySize allocated buffer containing the key. */
|
2017-08-10 16:30:42 +00:00
|
|
|
uint8_t const *mpw_kdf_scrypt(
|
2014-12-20 19:30:34 +00:00
|
|
|
const size_t keySize, const char *secret, const uint8_t *salt, const size_t saltSize,
|
|
|
|
uint64_t N, uint32_t r, uint32_t p);
|
2017-08-10 16:48:04 +00:00
|
|
|
/** Derive a subkey from the given key using the blake2b KDF.
|
2017-08-10 16:30:42 +00:00
|
|
|
* @return A new keySize allocated buffer containing the key. */
|
|
|
|
uint8_t const *mpw_kdf_blake2b(
|
|
|
|
const size_t subkeySize, const uint8_t *key, const size_t keySize,
|
|
|
|
const uint8_t *context, const size_t contextSize, const uint64_t id, const char *personal);
|
2017-08-05 21:33:45 +00:00
|
|
|
/** Calculate the MAC for the given message with the given key using SHA256-HMAC.
|
|
|
|
* @return A new 32-byte allocated buffer containing the MAC. */
|
2017-08-10 16:30:42 +00:00
|
|
|
uint8_t const *mpw_hash_hmac_sha256(
|
2014-12-20 19:30:34 +00:00
|
|
|
const uint8_t *key, const size_t keySize, const uint8_t *salt, const size_t saltSize);
|
2017-08-05 21:33:45 +00:00
|
|
|
/** Encrypt a plainBuf with the given key using AES-128-CBC.
|
|
|
|
* @return A new bufSize allocated buffer containing the cipherBuf. */
|
|
|
|
uint8_t const *mpw_aes_encrypt(
|
|
|
|
const uint8_t *key, const size_t keySize, const uint8_t *plainBuf, const size_t bufSize);
|
|
|
|
/** Decrypt a cipherBuf with the given key using AES-128-CBC.
|
|
|
|
* @return A new bufSize allocated buffer containing the plainBuf. */
|
|
|
|
uint8_t const *mpw_aes_decrypt(
|
|
|
|
const uint8_t *key, const size_t keySize, const uint8_t *cipherBuf, const size_t bufSize);
|
2014-12-20 19:30:34 +00:00
|
|
|
|
|
|
|
//// Visualizers.
|
|
|
|
|
2017-08-03 05:07:19 +00:00
|
|
|
/** Compose a formatted string.
|
|
|
|
* @return A C-string in a reused buffer, do not free or store it. */
|
|
|
|
const char *mpw_str(const char *format, ...);
|
2014-12-20 19:30:34 +00:00
|
|
|
/** Encode a buffer as a string of hexadecimal characters.
|
2015-01-15 22:43:41 +00:00
|
|
|
* @return A C-string in a reused buffer, do not free or store it. */
|
2014-12-20 19:30:34 +00:00
|
|
|
const char *mpw_hex(const void *buf, size_t length);
|
2015-02-27 13:49:04 +00:00
|
|
|
const char *mpw_hex_l(uint32_t number);
|
2014-12-20 19:30:34 +00:00
|
|
|
/** Encode a fingerprint for a buffer.
|
2015-01-15 22:43:41 +00:00
|
|
|
* @return A C-string in a reused buffer, do not free or store it. */
|
2017-08-01 12:31:39 +00:00
|
|
|
MPKeyID mpw_id_buf(const void *buf, size_t length);
|
2017-07-23 04:48:38 +00:00
|
|
|
/** Compare two fingerprints for equality.
|
|
|
|
* @return true if the buffers represent identical fingerprints. */
|
|
|
|
bool mpw_id_buf_equals(const char *id1, const char *id2);
|
2014-12-20 19:30:34 +00:00
|
|
|
/** Encode a visual fingerprint for a user.
|
|
|
|
* @return A newly allocated string. */
|
|
|
|
const char *mpw_identicon(const char *fullName, const char *masterPassword);
|
2015-01-15 22:43:41 +00:00
|
|
|
|
|
|
|
//// String utilities.
|
|
|
|
|
2015-02-18 22:32:33 +00:00
|
|
|
/** @return The amount of display characters in the given UTF-8 string. */
|
2016-11-03 14:04:18 +00:00
|
|
|
const size_t mpw_utf8_strlen(const char *utf8String);
|
2017-07-16 01:13:49 +00:00
|
|
|
|
|
|
|
#endif // _MPW_UTIL_H
|