2
0

passwordType -> resultType, add derived class and key type.

This commit is contained in:
Maarten Billemont
2017-08-10 12:30:42 -04:00
parent b1985a2bf2
commit 4f7c28563d
17 changed files with 519 additions and 379 deletions

View File

@@ -29,7 +29,7 @@
#define MP_p 2U
// Algorithm version helpers.
static const char *mpw_templateForType_v0(MPPasswordType type, uint16_t seedByte) {
static const char *mpw_templateForType_v0(MPResultType type, uint16_t seedByte) {
size_t count = 0;
const char **templates = mpw_templatesForType( type, &count );
@@ -70,7 +70,7 @@ static MPMasterKey mpw_masterKey_v0(
// Calculate the master key.
trc( "masterKey: scrypt( masterPassword, masterKeySalt, N=%lu, r=%u, p=%u )\n", MP_N, MP_r, MP_p );
MPMasterKey masterKey = mpw_scrypt( MPMasterKeySize, masterPassword, masterKeySalt, masterKeySaltSize, MP_N, MP_r, MP_p );
MPMasterKey masterKey = mpw_kdf_scrypt( MPMasterKeySize, masterPassword, masterKeySalt, masterKeySaltSize, MP_N, MP_r, MP_p );
mpw_free( masterKeySalt, masterKeySaltSize );
if (!masterKey) {
err( "Could not allocate master key: %s\n", strerror( errno ) );
@@ -113,10 +113,10 @@ static MPSiteKey mpw_siteKey_v0(
trc( "siteKey: hmac-sha256( masterKey.id=%s, siteSalt )\n",
mpw_id_buf( masterKey, MPMasterKeySize ) );
MPSiteKey siteKey = mpw_hmac_sha256( masterKey, MPMasterKeySize, siteSalt, siteSaltSize );
MPSiteKey siteKey = mpw_hash_hmac_sha256( masterKey, MPMasterKeySize, siteSalt, siteSaltSize );
mpw_free( siteSalt, siteSaltSize );
if (!siteKey) {
err( "Could not allocate site key: %s\n", strerror( errno ) );
err( "Could not derive site key: %s\n", strerror( errno ) );
return NULL;
}
trc( " => siteKey.id: %s\n", mpw_id_buf( siteKey, MPSiteKeySize ) );
@@ -124,12 +124,12 @@ static MPSiteKey mpw_siteKey_v0(
return siteKey;
}
static const char *mpw_sitePassword_v0(
MPSiteKey siteKey, const MPPasswordType passwordType) {
static const char *mpw_sitePasswordFromTemplate_v0(
MPMasterKey masterKey, MPSiteKey siteKey, const MPResultType resultType, const char *resultParam) {
// Determine the template.
const char *_siteKey = (const char *)siteKey;
const char *template = mpw_templateForType_v0( passwordType, htons( _siteKey[0] ) );
const char *template = mpw_templateForType_v0( resultType, htons( _siteKey[0] ) );
trc( "template: %u => %s\n", htons( _siteKey[0] ), template );
if (!template)
return NULL;
@@ -139,7 +139,7 @@ static const char *mpw_sitePassword_v0(
}
// Encode the password from the seed using the template.
char *const sitePassword = calloc( strlen( template ) + 1, sizeof( char ) );
char *sitePassword = calloc( strlen( template ) + 1, sizeof( char ) );
for (size_t c = 0; c < strlen( template ); ++c) {
sitePassword[c] = mpw_characterFromClass_v0( template[c], htons( _siteKey[c + 1] ) );
trc( " - class: %c, index: %5u (0x%02hX) => character: %c\n",
@@ -150,8 +150,80 @@ static const char *mpw_sitePassword_v0(
return sitePassword;
}
const char *mpw_encrypt_v0(
MPMasterKey masterKey, const char *plainText) {
static const char *mpw_sitePasswordFromCrypt_v0(
MPMasterKey masterKey, MPSiteKey siteKey, const MPResultType resultType, const char *cipherText) {
if (!cipherText) {
err( "Missing encrypted state.\n" );
return NULL;
}
// Base64-decode
uint8_t *cipherBuf = calloc( 1, mpw_base64_decode_max( cipherText ) );
size_t bufSize = (size_t)mpw_base64_decode( cipherBuf, cipherText );
if ((int)bufSize < 0) {
err( "Base64 decoding error." );
mpw_free( cipherBuf, mpw_base64_decode_max( cipherText ) );
return NULL;
}
trc( "b64 decoded: %zu bytes = %s\n", bufSize, mpw_hex( cipherBuf, bufSize ) );
// Decrypt
const uint8_t *plainBytes = mpw_aes_decrypt( masterKey, MPMasterKeySize, cipherBuf, bufSize );
const char *plainText = strndup( (char *)plainBytes, bufSize );
mpw_free( plainBytes, bufSize );
if (!plainText)
err( "AES decryption error: %s\n", strerror( errno ) );
trc( "decrypted -> plainText: %s = %s\n", plainText, mpw_hex( plainText, sizeof( plainText ) ) );
mpw_free( cipherBuf, bufSize );
return plainText;
}
static const char *mpw_sitePasswordFromDerive_v0(
MPMasterKey masterKey, MPSiteKey siteKey, const MPResultType resultType, const char *resultParam) {
switch (resultType) {
case MPResultTypeDeriveKey: {
if (!resultParam) {
err( "Missing key size parameter.\n" );
return NULL;
}
int resultParamInt = atoi( resultParam );
if (resultParamInt <= 0 || resultParamInt > UINT16_MAX || resultParamInt % 8 != 0) {
err( "Parameter is not a valid key size: %s\n", resultParam );
return NULL;
}
uint16_t keySize = (uint16_t)(resultParamInt / 8);
trc( "keySize: %u\n", keySize );
// Derive key
const uint8_t *resultKey = mpw_kdf_blake2b( keySize, siteKey, MPSiteKeySize, NULL, 0, 0, NULL );
if (!resultKey) {
err( "Could not derive result key: %s\n", strerror( errno ) );
return NULL;
}
// Base64-encode
size_t b64Max = mpw_base64_encode_max( keySize );
char *sitePassword = calloc( 1, b64Max + 1 );
if (mpw_base64_encode( sitePassword, resultKey, keySize ) < 0) {
err( "Base64 encoding error." );
mpw_free_string( sitePassword );
sitePassword = NULL;
}
trc( "b64 encoded -> key.id: %s\n", mpw_id_buf( sitePassword, strlen( sitePassword ) ) );
return sitePassword;
}
default:
err( "Unsupported derived password type: %d\n", resultType );
return NULL;
}
}
static const char *mpw_siteState_v0(
MPMasterKey masterKey, MPSiteKey siteKey, const MPResultType resultType, const char *plainText) {
// Encrypt
size_t bufSize = strlen( plainText );
@@ -175,28 +247,3 @@ const char *mpw_encrypt_v0(
return cipherText;
}
const char *mpw_decrypt_v0(
MPMasterKey masterKey, const char *cipherText) {
// Base64-decode
uint8_t *cipherBuf = calloc( 1, mpw_base64_decode_max( cipherText ) );
size_t bufSize = (size_t)mpw_base64_decode( cipherBuf, cipherText );
if ((int)bufSize < 0) {
err( "Base64 decoding error." );
mpw_free( cipherBuf, mpw_base64_decode_max( cipherText ) );
return NULL;
}
trc( "b64 decoded: %zu bytes = %s\n", bufSize, mpw_hex( cipherBuf, bufSize ) );
// Decrypt
const uint8_t *plainBytes = mpw_aes_decrypt( masterKey, MPMasterKeySize, cipherBuf, bufSize );
const char *plainText = strndup( (char *)plainBytes, bufSize );
mpw_free( plainBytes, bufSize );
if (!plainText)
err( "AES decryption error: %s\n", strerror( errno ) );
trc( "decrypted -> plainText: %s = %s\n", plainText, mpw_hex( plainText, sizeof( plainText ) ) );
mpw_free( cipherBuf, bufSize );
return plainText;
}