diff --git a/MasterPassword/C/mpw-cli.c b/MasterPassword/C/mpw-cli.c index c7532176..6cce2806 100644 --- a/MasterPassword/C/mpw-cli.c +++ b/MasterPassword/C/mpw-cli.c @@ -138,7 +138,7 @@ int main(int argc, char *const argv[]) { } return 1; default: - abort(); + ftl("Unexpected option: %c", opt); } if (optind < argc) siteName = argv[optind]; @@ -199,8 +199,8 @@ int main(int argc, char *const argv[]) { fprintf( stderr, "%s's password for %s:\n[ %s ]: ", fullName, siteName, Identicon( fullName, masterPassword ) ); // Output the password. - uint8_t *masterKey = mpw_masterKeyForUser( fullName, masterPassword ); - char *sitePassword = mpw_passwordForSite( masterKey, siteName, siteType, siteCounter, siteVariant, siteContextString ); + const uint8_t *masterKey = mpw_masterKeyForUser( fullName, masterPassword ); + const char *sitePassword = mpw_passwordForSite( masterKey, siteName, siteType, siteCounter, siteVariant, siteContextString ); fprintf( stdout, "%s\n", sitePassword ); return 0; diff --git a/MasterPassword/C/mpw.c b/MasterPassword/C/mpw.c index e282698c..ec229e7f 100644 --- a/MasterPassword/C/mpw.c +++ b/MasterPassword/C/mpw.c @@ -16,115 +16,101 @@ #define MP_dkLen 64 #define MP_hash PearlHashSHA256 -void mpw_bufPush(void *buffer, size_t *bufferSize, void *pushBuffer, size_t pushSize) { +static void mpw_pushBuf(uint8_t **const buffer, size_t *const bufferSize, const void *pushBuffer, const size_t pushSize) { - void *pushDst = buffer + *bufferSize; *bufferSize += pushSize; - realloc( buffer, *bufferSize ); + *buffer = realloc( *buffer, *bufferSize ); + uint8_t *pushDst = *buffer + *bufferSize - pushSize; memcpy( pushDst, pushBuffer, pushSize ); } -uint8_t *mpw_masterKeyForUser(const char *fullName, const char *masterPassword) { +static void mpw_pushString(uint8_t **buffer, size_t *const bufferSize, const char *pushString) { + + mpw_pushBuf( buffer, bufferSize, pushString, strlen( pushString ) ); +} + +static void mpw_pushInt(uint8_t **const buffer, size_t *const bufferSize, const uint32_t pushInt) { + + mpw_pushBuf( buffer, bufferSize, &pushInt, sizeof( pushInt ) ); +} + +static void mpw_free(void *const buffer, const size_t bufferSize) { + + memset( buffer, 0, bufferSize ); + free( buffer ); +} + +const uint8_t *mpw_masterKeyForUser(const char *fullName, const char *masterPassword) { - // Calculate the master key salt. const char *mpKeyScope = ScopeForVariant( MPSiteVariantPassword ); - const uint32_t n_fullNameLength = htonl( strlen( fullName ) ); - const size_t masterKeySaltLength = strlen( mpKeyScope ) + sizeof( n_fullNameLength ) + strlen( fullName ); - char *masterKeySalt = (char *)malloc( masterKeySaltLength ); - if (!masterKeySalt) - ftl( "Could not allocate master key salt: %d\n", errno ); - - char *mKS = masterKeySalt; - memcpy( mKS, mpKeyScope, strlen( mpKeyScope ) ); - mKS += strlen( mpKeyScope ); - memcpy( mKS, &n_fullNameLength, sizeof( n_fullNameLength ) ); - mKS += sizeof( n_fullNameLength ); - memcpy( mKS, fullName, strlen( fullName ) ); - mKS += strlen( fullName ); - trc( "fullName: %s\n", fullName ); trc( "masterPassword: %s\n", masterPassword ); trc( "key scope: %s\n", mpKeyScope ); - trc( "masterKeySalt ID: %s\n", IDForBuf( masterKeySalt, masterKeySaltLength ) ); - if (mKS - masterKeySalt != masterKeySaltLength) - ftl( "Unexpected master key salt length." ); + + // Calculate the master key salt. + // masterKeySalt = mpKeyScope . #fullName . fullName + size_t masterKeySaltSize = 0; + uint8_t *masterKeySalt = NULL; + mpw_pushString( &masterKeySalt, &masterKeySaltSize, mpKeyScope ); + mpw_pushInt( &masterKeySalt, &masterKeySaltSize, htonl( strlen( fullName ) ) ); + mpw_pushString( &masterKeySalt, &masterKeySaltSize, fullName ); + if (!masterKeySalt) + ftl( "Could not allocate master key salt: %d\n", errno ); + trc( "masterKeySalt ID: %s\n", IDForBuf( masterKeySalt, masterKeySaltSize ) ); // Calculate the master key. + // masterKey = scrypt( masterPassword, masterKeySalt ) uint8_t *masterKey = (uint8_t *)malloc( MP_dkLen ); - if (!masterKey) { - fprintf( stderr, "Could not allocate master key: %d\n", errno ); - abort(); - } - if (crypto_scrypt( (const uint8_t *)masterPassword, strlen( masterPassword ), (const uint8_t *)masterKeySalt, masterKeySaltLength, MP_N, - MP_r, MP_p, masterKey, MP_dkLen ) < 0) { - fprintf( stderr, "Could not generate master key: %d\n", errno ); - abort(); - } - memset( masterKeySalt, 0, masterKeySaltLength ); - free( masterKeySalt ); + if (!masterKey) + ftl( "Could not allocate master key: %d\n", errno ); + if (crypto_scrypt( (const uint8_t *)masterPassword, strlen( masterPassword ), + masterKeySalt, masterKeySaltSize, MP_N, MP_r, MP_p, masterKey, MP_dkLen ) < 0) + ftl( "Could not generate master key: %d\n", errno ); + mpw_free( masterKeySalt, masterKeySaltSize ); trc( "masterKey ID: %s\n", IDForBuf( masterKey, MP_dkLen ) ); return masterKey; } -char *mpw_passwordForSite(const uint8_t *masterKey, const char *siteName, const MPSiteType siteType, const uint32_t siteCounter, +const char *mpw_passwordForSite(const uint8_t *masterKey, const char *siteName, const MPSiteType siteType, const uint32_t siteCounter, const MPSiteVariant siteVariant, const char *siteContext) { - // Calculate the site seed. + const char *siteScope = ScopeForVariant( siteVariant ); trc( "siteName: %s\n", siteName ); trc( "siteCounter: %d\n", siteCounter ); trc( "siteVariant: %d\n", siteVariant ); trc( "siteType: %d\n", siteType ); - const char *siteScope = ScopeForVariant( siteVariant ); trc( "site scope: %s, context: %s\n", siteScope, siteContext == NULL? "": siteContext ); - const uint32_t n_siteNameLength = htonl( strlen( siteName ) ); - const uint32_t n_siteCounter = htonl( siteCounter ); - const uint32_t n_siteContextLength = siteContext == NULL? 0: htonl( strlen( siteContext ) ); - size_t sitePasswordInfoLength = strlen( siteScope ) + sizeof( n_siteNameLength ) + strlen( siteName ) + sizeof( n_siteCounter ); - if (siteContext) - sitePasswordInfoLength += sizeof( n_siteContextLength ) + strlen( siteContext ); - char *sitePasswordInfo = (char *)malloc( sitePasswordInfoLength ); - if (!sitePasswordInfo) { - fprintf( stderr, "Could not allocate site seed: %d\n", errno ); - abort(); - } - char *sPI = sitePasswordInfo; - memcpy( sPI, siteScope, strlen( siteScope ) ); - sPI += strlen( siteScope ); - memcpy( sPI, &n_siteNameLength, sizeof( n_siteNameLength ) ); - sPI += sizeof( n_siteNameLength ); - memcpy( sPI, siteName, strlen( siteName ) ); - sPI += strlen( siteName ); - memcpy( sPI, &n_siteCounter, sizeof( n_siteCounter ) ); - sPI += sizeof( n_siteCounter ); + // Calculate the site seed. + // sitePasswordSeed = hmac-sha256( masterKey, siteScope . #siteName . siteName . siteCounter . #siteContext . siteContext ) + size_t sitePasswordInfoSize = 0; + uint8_t *sitePasswordInfo = NULL; + mpw_pushString( &sitePasswordInfo, &sitePasswordInfoSize, siteScope ); + mpw_pushInt( &sitePasswordInfo, &sitePasswordInfoSize, htonl( strlen( siteName ) ) ); + mpw_pushString( &sitePasswordInfo, &sitePasswordInfoSize, siteName ); + mpw_pushInt( &sitePasswordInfo, &sitePasswordInfoSize, htonl( siteCounter ) ); if (siteContext) { - memcpy( sPI, &n_siteContextLength, sizeof( n_siteContextLength ) ); - sPI += sizeof( n_siteContextLength ); - memcpy( sPI, siteContext, strlen( siteContext ) ); - sPI += strlen( siteContext ); + mpw_pushInt( &sitePasswordInfo, &sitePasswordInfoSize, htonl( strlen( siteContext ) ) ); + mpw_pushString( &sitePasswordInfo, &sitePasswordInfoSize, siteContext ); } - if (sPI - sitePasswordInfo != sitePasswordInfoLength) - abort(); - trc( "seed from: hmac-sha256(masterKey, %s | %s | %s | %s | %s | %s)\n", siteScope, - Hex( &n_siteNameLength, sizeof( n_siteNameLength ) ), siteName, Hex( &n_siteCounter, sizeof( n_siteCounter ) ), - Hex( &n_siteContextLength, sizeof( n_siteContextLength ) ), siteContext ); - trc( "sitePasswordInfo ID: %s\n", IDForBuf( sitePasswordInfo, sitePasswordInfoLength ) ); + if (!sitePasswordInfo) + ftl( "Could not allocate site seed: %d\n", errno ); + trc( "sitePasswordInfo ID: %s\n", IDForBuf( sitePasswordInfo, sitePasswordInfoSize ) ); uint8_t sitePasswordSeed[32]; - HMAC_SHA256_Buf( masterKey, MP_dkLen, sitePasswordInfo, sitePasswordInfoLength, sitePasswordSeed ); - memset( sitePasswordInfo, 0, sitePasswordInfoLength ); - free( sitePasswordInfo ); + HMAC_SHA256_Buf( masterKey, MP_dkLen, sitePasswordInfo, sitePasswordInfoSize, sitePasswordSeed ); + mpw_free( sitePasswordInfo, sitePasswordInfoSize ); trc( "sitePasswordSeed ID: %s\n", IDForBuf( sitePasswordSeed, 32 ) ); // Determine the template. const char *template = TemplateForType( siteType, sitePasswordSeed[0] ); trc( "type %d, template: %s\n", siteType, template ); if (strlen( template ) > 32) - abort(); + ftl( "Template too long for password seed: %d", strlen( template ) ); // Encode the password from the seed using the template. - char *sitePassword = (char *)calloc( strlen( template ) + 1, sizeof( char ) ); + char *const sitePassword = calloc( strlen( template ) + 1, sizeof( char ) ); for (int c = 0; c < strlen( template ); ++c) { sitePassword[c] = CharacterFromClass( template[c], sitePasswordSeed[c + 1] ); trc( "class %c, index %u (0x%02X) -> character: %c\n", template[c], sitePasswordSeed[c + 1], sitePasswordSeed[c + 1], diff --git a/MasterPassword/C/mpw.h b/MasterPassword/C/mpw.h index a9238599..2d333fd2 100644 --- a/MasterPassword/C/mpw.h +++ b/MasterPassword/C/mpw.h @@ -1,6 +1,6 @@ -uint8_t *mpw_masterKeyForUser( +const uint8_t *mpw_masterKeyForUser( const char *fullName, const char *masterPassword); -char *mpw_passwordForSite( +const char *mpw_passwordForSite( const uint8_t *masterKey, const char *siteName, const MPSiteType siteType, const uint32_t siteCounter, const MPSiteVariant siteVariant, const char *siteContext);