2
0

Implement algorithm support for hybrid personal passwords.

This commit is contained in:
Maarten Billemont
2017-08-05 17:33:45 -04:00
parent 228f8e4ed1
commit 322e056661
13 changed files with 400 additions and 38 deletions

171
core/c/base64.c Normal file
View File

@@ -0,0 +1,171 @@
/* ====================================================================
* Copyright (c) 1995-1999 The Apache Group. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* 4. The names "Apache Server" and "Apache Group" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Group and was originally based
* on public domain software written at the National Center for
* Supercomputing Applications, University of Illinois, Urbana-Champaign.
* For more information on the Apache Group and the Apache HTTP server
* project, please see <http://www.apache.org/>.
*/
#include "base64.h"
/* aaaack but it's fast and const should make it shared text page. */
static const unsigned char pr2six[256] =
{
/* ASCII table */
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,
64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64,
64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
};
size_t Base64decode_len(const char *bufcoded) {
size_t nbytesdecoded;
register const unsigned char *bufin;
register int nprbytes;
bufin = (const unsigned char *)bufcoded;
while (pr2six[*(bufin++)] <= 63);
nprbytes = (int)(bufin - (const unsigned char *)bufcoded) - 1;
nbytesdecoded = (size_t)(((nprbytes + 3) / 4) * 3);
return nbytesdecoded;
}
int Base64decode(uint8_t *bufplain, const char *bufcoded) {
int nbytesdecoded;
register const unsigned char *bufin;
register unsigned char *bufout;
register int nprbytes;
bufin = (const unsigned char *)bufcoded;
while (pr2six[*(bufin++)] <= 63);
nprbytes = (int)(bufin - (const unsigned char *)bufcoded) - 1;
nbytesdecoded = ((nprbytes + 3) / 4) * 3;
bufout = bufplain;
bufin = (const unsigned char *)bufcoded;
while (nprbytes > 4) {
*(bufout++) = (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
*(bufout++) = (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
*(bufout++) = (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
bufin += 4;
nprbytes -= 4;
}
/* Note: (nprbytes == 1) would be an error, so just ingore that case */
if (nprbytes > 1) {
*(bufout++) = (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
}
if (nprbytes > 2) {
*(bufout++) = (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
}
if (nprbytes > 3) {
*(bufout++) = (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
}
nbytesdecoded -= (4 - nprbytes) & 3;
return nbytesdecoded;
}
static const char basis_64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
size_t Base64encode_len(size_t len) {
return ((len + 2) / 3 * 4);
}
int Base64encode(char *encoded, const uint8_t *string, size_t len) {
int i;
char *p;
p = encoded;
for (i = 0; i < len - 2; i += 3) {
*p++ = basis_64[(string[i] >> 2) & 0x3F];
*p++ = basis_64[((string[i] & 0x3) << 4) |
((string[i + 1] & 0xF0) >> 4)];
*p++ = basis_64[((string[i + 1] & 0xF) << 2) |
((string[i + 2] & 0xC0) >> 6)];
*p++ = basis_64[string[i + 2] & 0x3F];
}
if (i < len) {
*p++ = basis_64[(string[i] >> 2) & 0x3F];
if (i == (len - 1)) {
*p++ = basis_64[((string[i] & 0x3) << 4)];
*p++ = '=';
}
else {
*p++ = basis_64[((string[i] & 0x3) << 4) |
((string[i + 1] & 0xF0) >> 4)];
*p++ = basis_64[((string[i + 1] & 0xF) << 2)];
}
*p++ = '=';
}
return (int)(p - encoded);
}

64
core/c/base64.h Normal file
View File

@@ -0,0 +1,64 @@
/* ====================================================================
* Copyright (c) 1995-1999 The Apache Group. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* 4. The names "Apache Server" and "Apache Group" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Group and was originally based
* on public domain software written at the National Center for
* Supercomputing Applications, University of Illinois, Urbana-Champaign.
* For more information on the Apache Group and the Apache HTTP server
* project, please see <http://www.apache.org/>.
*/
#include <stddef.h>
#include <stdint.h>
size_t Base64decode_len(const char *bufcoded);
int Base64decode(uint8_t *bufplain, const char *bufcoded);
size_t Base64encode_len(size_t len);
int Base64encode(char *encoded, const uint8_t *string, size_t len);

View File

@@ -22,6 +22,7 @@
#include "mpw-types.h"
#include "mpw-util.h"
#include "base64.h"
#define MP_N 32768
#define MP_r 8
@@ -155,11 +156,38 @@ static const char *mpw_sitePassword_v0(
const char *mpw_encrypt_v0(
MPMasterKey masterKey, const char *plainText) {
return NULL; // TODO: aes128_cbc
// Encrypt
dbg( "-- encrypting plainText: %s\n", plainText );
size_t bufSize = strlen( plainText );
const uint8_t *cipherBuf = mpw_aes_encrypt( masterKey, MPMasterKeySize, (const uint8_t *)plainText, bufSize );
dbg( "-- cipherBuf: %lu bytes = ", bufSize );
printb( cipherBuf, bufSize );
// Base64-encode
char *cipherText = calloc( 1, Base64encode_len( bufSize ) + 1 );
Base64encode( cipherText, cipherBuf, bufSize );
dbg( "-- b64 encoded -> cipherText: %s\n", cipherText );
mpw_free( cipherBuf, bufSize );
return cipherText;
}
const char *mpw_decrypt_v0(
MPMasterKey masterKey, const char *cipherText) {
return NULL; // TODO: aes128_cbc
// Base64-decode
dbg( "-- decrypting cipherText: %s\n", cipherText );
size_t bufSize = Base64decode_len( cipherText ) + 1;
uint8_t *cipherBuf = calloc( 1, bufSize );
Base64decode( cipherBuf, cipherText );
dbg( "-- b64 decoded: %lu bytes = ", bufSize );
printb( cipherBuf, bufSize );
// Decrypt
const char *plainText = (const char *)mpw_aes_decrypt( masterKey, MPMasterKeySize, cipherBuf, bufSize );
dbg( "-- decrypted -> plainText: %s\n", plainText );
mpw_free( cipherBuf, bufSize );
return plainText;
}

View File

@@ -136,11 +136,11 @@ static const char *mpw_sitePassword_v1(
const char *mpw_encrypt_v1(
MPMasterKey masterKey, const char *plainText) {
return NULL; // TODO: aes128_cbc
return mpw_encrypt_v0( masterKey, plainText );
}
const char *mpw_decrypt_v1(
MPMasterKey masterKey, const char *cipherText) {
return NULL; // TODO: aes128_cbc
return mpw_decrypt_v0( masterKey, cipherText );
}

View File

@@ -136,11 +136,11 @@ static const char *mpw_sitePassword_v2(
const char *mpw_encrypt_v2(
MPMasterKey masterKey, const char *plainText) {
return NULL; // TODO: aes128_cbc
return mpw_encrypt_v1( masterKey, plainText );
}
const char *mpw_decrypt_v2(
MPMasterKey masterKey, const char *cipherText) {
return NULL; // TODO: aes128_cbc
return mpw_decrypt_v1( masterKey, cipherText );
}

View File

@@ -136,11 +136,11 @@ static const char *mpw_sitePassword_v3(
const char *mpw_encrypt_v3(
MPMasterKey masterKey, const char *plainText) {
return NULL; // TODO: aes128_cbc
return mpw_encrypt_v2( masterKey, plainText );
}
const char *mpw_decrypt_v3(
MPMasterKey masterKey, const char *cipherText) {
return NULL; // TODO: aes128_cbc
return mpw_decrypt_v2( masterKey, cipherText );
}

View File

@@ -57,7 +57,7 @@ json_object *mpw_get_json_section(
char *sectionTokenizer = strdup( section ), *sectionToken = sectionTokenizer;
for (sectionToken = strtok( sectionToken, "." ); sectionToken; sectionToken = strtok( NULL, "." ))
if (!json_object_object_get_ex( json_value, sectionToken, &json_value ) || !json_value) {
dbg( "While resolving: %s: Missing value for: %s\n", section, sectionToken );
trc( "While resolving: %s: Missing value for: %s\n", section, sectionToken );
json_value = NULL;
break;
}

View File

@@ -55,7 +55,8 @@ MPMarshalledSite *mpw_marshall_site(
realloc( marshalledUser->sites, sizeof( MPMarshalledSite ) * (++marshalledUser->sites_count) )))
return NULL;
marshalledUser->sites[marshalledUser->sites_count - 1] = (MPMarshalledSite){
MPMarshalledSite *site = &marshalledUser->sites[marshalledUser->sites_count - 1];
*site = (MPMarshalledSite){
.name = strdup( siteName ),
.content = NULL,
.type = siteType,
@@ -72,7 +73,7 @@ MPMarshalledSite *mpw_marshall_site(
.questions_count = 0,
.questions = NULL,
};
return marshalledUser->sites + sizeof( MPMarshalledSite ) * (marshalledUser->sites_count - 1);
return site;
};
MPMarshalledQuestion *mpw_marshal_question(
@@ -82,10 +83,11 @@ MPMarshalledQuestion *mpw_marshal_question(
realloc( marshalledSite->questions, sizeof( MPMarshalledQuestion ) * (++marshalledSite->questions_count) )))
return NULL;
marshalledSite->questions[marshalledSite->questions_count - 1] = (MPMarshalledQuestion){
MPMarshalledQuestion *question = &marshalledSite->questions[marshalledSite->questions_count - 1];
*question = (MPMarshalledQuestion){
.keyword = strdup( keyword ),
};
return marshalledSite->questions + sizeof( MPMarshalledSite ) * (marshalledSite->questions_count - 1);
return question;
}
bool mpw_marshal_free(
@@ -130,9 +132,9 @@ static bool mpw_marshall_write_flat(
mpw_string_pushf( out, "# Master Password site export\n" );
if (user->redacted)
mpw_string_pushf( out, "# Export of site names and passwords in clear-text.\n" );
else
mpw_string_pushf( out, "# Export of site names and stored passwords (unless device-private) encrypted with the master key.\n" );
else
mpw_string_pushf( out, "# Export of site names and passwords in clear-text.\n" );
mpw_string_pushf( out, "# \n" );
mpw_string_pushf( out, "##\n" );
mpw_string_pushf( out, "# Format: %d\n", 1 );
@@ -161,6 +163,7 @@ static bool mpw_marshall_write_flat(
const char *content = NULL;
if (!user->redacted) {
// Clear Text
if (!mpw_update_masterKey( &masterKey, &masterKeyAlgorithm, site.algorithm, user->name, user->masterPassword )) {
*error = (MPMarshallError){ MPMarshallErrorInternal, "Couldn't derive master key." };
return false;
@@ -174,6 +177,7 @@ static bool mpw_marshall_write_flat(
else if (site.type & MPSiteFeatureExportContent && site.content && strlen( site.content ))
content = mpw_decrypt( masterKey, site.content, site.algorithm );
} else if (site.type & MPSiteFeatureExportContent && site.content && strlen( site.content ))
// Redacted
content = strdup( site.content );
if (strftime( dateString, sizeof( dateString ), "%FT%TZ", gmtime( &site.lastUsed ) ))
@@ -242,6 +246,7 @@ static bool mpw_marshall_write_json(
const char *content = NULL;
if (!user->redacted) {
// Clear Text
if (!mpw_update_masterKey( &masterKey, &masterKeyAlgorithm, site.algorithm, user->name, user->masterPassword )) {
*error = (MPMarshallError){ MPMarshallErrorInternal, "Couldn't derive master key." };
return false;
@@ -256,6 +261,7 @@ static bool mpw_marshall_write_json(
content = mpw_decrypt( masterKey, site.content, site.algorithm );
}
else if (site.type & MPSiteFeatureExportContent && site.content && strlen( site.content ))
// Redacted
content = strdup( site.content );
json_object *json_site = json_object_new_object();
@@ -284,6 +290,7 @@ static bool mpw_marshall_write_json(
json_object_object_add( json_site_questions, question.keyword, json_site_question );
if (!user->redacted) {
// Clear Text
MPSiteKey siteKey = mpw_siteKey( masterKey, site.name, 1, MPKeyPurposeRecovery, question.keyword, site.algorithm );
const char *answer = mpw_sitePassword( siteKey, MPPasswordTypeGeneratedPhrase, site.algorithm );
mpw_free( siteKey, MPSiteKeySize );
@@ -500,7 +507,8 @@ static MPMarshalledUser *mpw_marshall_read_flat(
site->uses = (unsigned int)atoi( str_uses );
site->lastUsed = siteLastUsed;
if (siteContent && strlen( siteContent )) {
if (user->redacted) {
if (!user->redacted) {
// Clear Text
if (!mpw_update_masterKey( &masterKey, &masterKeyAlgorithm, site->algorithm, fullName, masterPassword )) {
*error = (MPMarshallError){ MPMarshallErrorInternal, "Couldn't derive master key." };
return NULL;
@@ -509,6 +517,7 @@ static MPMarshalledUser *mpw_marshall_read_flat(
site->content = mpw_encrypt( masterKey, siteContent, site->algorithm );
}
else
// Redacted
site->content = strdup( siteContent );
}
}
@@ -653,7 +662,8 @@ static MPMarshalledUser *mpw_marshall_read_json(
site->uses = siteUses;
site->lastUsed = siteLastUsed;
if (siteContent && strlen( siteContent )) {
if (user->redacted) {
if (!user->redacted) {
// Clear Text
if (!mpw_update_masterKey( &masterKey, &masterKeyAlgorithm, site->algorithm, fullName, masterPassword )) {
*error = (MPMarshallError){ MPMarshallErrorInternal, "Couldn't derive master key." };
return NULL;
@@ -662,6 +672,7 @@ static MPMarshalledUser *mpw_marshall_read_json(
site->content = mpw_encrypt( masterKey, siteContent, site->algorithm );
}
else
// Redacted
site->content = strdup( siteContent );
}

View File

@@ -30,6 +30,9 @@
#include <scrypt/sha256.h>
#elif HAS_SODIUM
#include "sodium.h"
#ifdef SODIUM_LIBRARY_MINIMAL
#include "crypto_stream_aes128ctr.h"
#endif
#endif
#include "mpw-util.h"
@@ -67,6 +70,9 @@ bool mpw_push_string(uint8_t **const buffer, size_t *const bufferSize, const cha
bool mpw_string_push(char **const string, const char *pushString) {
if (!*string)
*string = calloc( 1, sizeof( char ) );
size_t stringLength = strlen( *string );
return pushString && mpw_push_buf( (uint8_t **const)string, &stringLength, pushString, strlen( pushString ) + 1 );
}
@@ -123,37 +129,79 @@ uint8_t const *mpw_scrypt(const size_t keySize, const char *secret, const uint8_
mpw_free( key, keySize );
return NULL;
}
#else
#error No crypto support for mpw_scrypt.
#endif
return key;
}
uint8_t const *mpw_hmac_sha256(const uint8_t *key, const size_t keySize, const uint8_t *salt, const size_t saltSize) {
uint8_t const *mpw_hmac_sha256(const uint8_t *key, const size_t keySize, const uint8_t *message, const size_t messageSize) {
#if HAS_CPERCIVA
uint8_t *const buffer = malloc( 32 );
if (!buffer)
if (!key || !keySize || !message || !messageSize)
return NULL;
HMAC_SHA256_Buf( key, keySize, salt, saltSize, buffer );
return buffer;
#if HAS_CPERCIVA
uint8_t *const mac = malloc( 32 );
if (!mac)
return NULL;
HMAC_SHA256_Buf( key, keySize, message, messageSize, mac );
#elif HAS_SODIUM
uint8_t *const buffer = malloc( crypto_auth_hmacsha256_BYTES );
if (!buffer)
uint8_t *const mac = malloc( crypto_auth_hmacsha256_BYTES );
if (!mac)
return NULL;
crypto_auth_hmacsha256_state state;
if (crypto_auth_hmacsha256_init( &state, key, keySize ) != 0 ||
crypto_auth_hmacsha256_update( &state, salt, saltSize ) != 0 ||
crypto_auth_hmacsha256_final( &state, buffer ) != 0) {
mpw_free( buffer, crypto_auth_hmacsha256_BYTES );
crypto_auth_hmacsha256_update( &state, message, messageSize ) != 0 ||
crypto_auth_hmacsha256_final( &state, mac ) != 0) {
mpw_free( mac, crypto_auth_hmacsha256_BYTES );
return NULL;
}
return buffer;
#else
#error No crypto support for mpw_hmac_sha256.
#endif
return NULL;
return mac;
}
static uint8_t const *mpw_aes(bool encrypt, const uint8_t *key, const size_t keySize, const uint8_t *buf, const size_t bufSize) {
#if HAS_SODIUM
if (!key || keySize < crypto_stream_KEYBYTES)
return NULL;
uint8_t cipherKey[crypto_stream_KEYBYTES];
memcpy( cipherKey, key, sizeof( cipherKey ) );
uint8_t nonce[crypto_stream_NONCEBYTES];
bzero( (void *)nonce, sizeof( nonce ) );
if (encrypt) {
uint8_t *const cipherBuf = malloc( bufSize );
crypto_stream_aes128ctr_xor( cipherBuf, buf, bufSize, nonce, cipherKey );
return cipherBuf;
} else {
uint8_t *const plainBuf = malloc( bufSize );
crypto_stream_aes128ctr( plainBuf, bufSize, nonce, cipherKey );
for (size_t c = 0; c < bufSize; ++c)
plainBuf[c] = buf[c] ^ plainBuf[c];
return plainBuf;
}
#else
#error No crypto support for mpw_aes.
#endif
}
uint8_t const *mpw_aes_encrypt(const uint8_t *key, const size_t keySize, const uint8_t *plainBuf, const size_t bufSize) {
return mpw_aes( true, key, keySize, plainBuf, bufSize );
}
uint8_t const *mpw_aes_decrypt(const uint8_t *key, const size_t keySize, const uint8_t *cipherBuf, const size_t bufSize) {
return mpw_aes( false, key, keySize, cipherBuf, bufSize );
}
MPKeyID mpw_id_buf(const void *buf, size_t length) {
@@ -167,6 +215,8 @@ MPKeyID mpw_id_buf(const void *buf, size_t length) {
#elif HAS_SODIUM
uint8_t hash[crypto_hash_sha256_BYTES];
crypto_hash_sha256( hash, buf, length );
#else
#error No crypto support for mpw_id_buf.
#endif
return mpw_hex( hash, sizeof( hash ) / sizeof( uint8_t ) );
@@ -325,3 +375,10 @@ const size_t mpw_utf8_strlen(const char *utf8String) {
return charlen;
}
void printb(const void *p, size_t size) {
for (int i = 0; i < size; ++i)
dbg( "%02hhX ", ((const uint8_t *)p)[i] );
dbg( "\n" );
}

View File

@@ -121,15 +121,23 @@ bool mpw_free_string(
//// Cryptographic functions.
/** Perform a scrypt-based key derivation on the given key using the given salt and scrypt parameters.
* @return A new keySize-size allocated buffer. */
/** Derive a key from the given secret and salt using the scrypt KDF.
* @return A new keySize allocated buffer containing the key. */
uint8_t const *mpw_scrypt(
const size_t keySize, const char *secret, const uint8_t *salt, const size_t saltSize,
uint64_t N, uint32_t r, uint32_t p);
/** Calculate a SHA256-based HMAC by encrypting the given salt with the given key.
* @return A new 32-byte allocated buffer. */
/** Calculate the MAC for the given message with the given key using SHA256-HMAC.
* @return A new 32-byte allocated buffer containing the MAC. */
uint8_t const *mpw_hmac_sha256(
const uint8_t *key, const size_t keySize, const uint8_t *salt, const size_t saltSize);
/** 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);
//// Visualizers.
@@ -155,4 +163,6 @@ const char *mpw_identicon(const char *fullName, const char *masterPassword);
/** @return The amount of display characters in the given UTF-8 string. */
const size_t mpw_utf8_strlen(const char *utf8String);
void printb(const void *p, size_t size);
#endif // _MPW_UTIL_H