passwordType -> resultType, add derived class and key type.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user