Compare commits
24 Commits
2.1-appsto
...
2.1-cli1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
10f100186c | ||
|
|
2af2351ebf | ||
|
|
49b3fe7913 | ||
|
|
9d926be8ae | ||
|
|
c3474de2ff | ||
|
|
68b9b4e09a | ||
|
|
b810c1032b | ||
|
|
a4ab3c7bc9 | ||
|
|
039547b735 | ||
|
|
6f741f6f2f | ||
|
|
38d4b761b7 | ||
|
|
18f8ebb9dc | ||
|
|
794d064a99 | ||
|
|
090b274363 | ||
|
|
25ba87f119 | ||
|
|
f0b659a0c7 | ||
|
|
7736788920 | ||
|
|
e3be98f3ad | ||
|
|
d9b1b44de0 | ||
|
|
c3c2de5d14 | ||
|
|
6aa50bac04 | ||
|
|
5268039c3d | ||
|
|
0d66d4660e | ||
|
|
e981df3c8b |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -32,7 +32,10 @@ Press/MasterPassword_PressKit/MasterPassword_pressrelease_*.pdf
|
|||||||
MasterPassword/Java/**/target
|
MasterPassword/Java/**/target
|
||||||
|
|
||||||
# C
|
# C
|
||||||
|
MasterPassword/C/VERSION
|
||||||
MasterPassword/C/*.o
|
MasterPassword/C/*.o
|
||||||
|
MasterPassword/C/mpw-*.tar.gz
|
||||||
MasterPassword/C/mpw
|
MasterPassword/C/mpw
|
||||||
|
MasterPassword/C/mpw-bench
|
||||||
MasterPassword/C/lib/*/*
|
MasterPassword/C/lib/*/*
|
||||||
!MasterPassword/C/lib/*/.source
|
!MasterPassword/C/lib/*/.source
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,258 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Run with -DDEBUG to enable trace-level output.
|
#
|
||||||
|
# TROUBLESHOOTING
|
||||||
|
# - To enable verbose algorithm/implementation debugging, use ./build -DDEBUG
|
||||||
|
# - If you see 'undefined reference to `clock_gettime'', try ./build -lrt instead
|
||||||
|
#
|
||||||
|
# BUGS
|
||||||
|
# masterpassword@lyndir.com
|
||||||
|
#
|
||||||
|
# AUTHOR
|
||||||
|
# Maarten Billemont
|
||||||
|
#
|
||||||
|
cd "${BASH_SOURCE%/*}"
|
||||||
|
shopt -s extglob
|
||||||
|
set -e
|
||||||
|
|
||||||
[[ -e lib/scrypt/scryptenc.o ]] || { echo >&2 "Missing scrypt. First get and build the scrypt source in lib/scrypt from <$(<lib/scrypt/.source)>.\n"; exit 1; }
|
|
||||||
|
|
||||||
deps=( -I"lib/scrypt/lib" -I"lib/scrypt/libcperciva" -l "crypto_aesctr.o" -l "sha256.o" -l "crypto_scrypt-nosse.o" -l "memlimit.o" -l "scryptenc_cpuperf.o" -l"scryptenc.o" -l"crypto" -L"." -L"lib/scrypt" )
|
### CONFIGURATION
|
||||||
|
|
||||||
gcc "${deps[@]}" -Qunused-arguments -c types.c -o types.o "$@"
|
# Targets to build.
|
||||||
gcc "${deps[@]}" -Qunused-arguments -l"types.o" mpw.c -o mpw "$@"
|
if [[ $targets ]]; then
|
||||||
|
read -ra targets <<< "$targets"
|
||||||
|
else
|
||||||
|
# Default targets.
|
||||||
|
# Modify here or override using targets='mpw mpw-bench' ./build
|
||||||
|
targets=(
|
||||||
|
mpw # C CLI version of Master Password.
|
||||||
|
#mpw-bench # C CLI Master Password benchmark utility.
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
### DEPENDENCIES
|
||||||
|
|
||||||
|
fetch() {
|
||||||
|
if hash wget 2>/dev/null; then
|
||||||
|
wget -O "${1##*/}" "$1"
|
||||||
|
elif hash curl 2>/dev/null; then
|
||||||
|
curl "$1" > "${1##*/}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
unpack() {
|
||||||
|
if [[ $1 = *.tar.gz || $1 = *.tgz ]]; then
|
||||||
|
tar -xvzf "$1"
|
||||||
|
|
||||||
|
elif [[ $1 = *.tar.bz2 || $1 = *.tbz2 ]]; then
|
||||||
|
tar -xvjf "$1"
|
||||||
|
|
||||||
|
elif [[ $1 = *.tar ]]; then
|
||||||
|
tar -xvf "$1"
|
||||||
|
|
||||||
|
else
|
||||||
|
echo 2>&1 "Don't know how to unpack: $1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf 'Verifying package: %s, against digest: %s...' "$1" "$2"
|
||||||
|
[[ $(openssl sha < "$1") = $2 ]] || {
|
||||||
|
printf ' mismatch!\n'
|
||||||
|
echo 2>&1 "Downloaded package doesn't match digest."
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
printf ' OK!\n'
|
||||||
|
|
||||||
|
files=( !("$1") )
|
||||||
|
if [[ -d $files ]] && (( ${#files[@]} == 1 )); then
|
||||||
|
mv "$files"/* .
|
||||||
|
rmdir "$files"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
fetchSource() (
|
||||||
|
source .source
|
||||||
|
|
||||||
|
if [[ $pkg && -e "${pkg##*/}" ]]; then
|
||||||
|
files=( !("${pkg##*/}") )
|
||||||
|
[[ -e $files ]] || {
|
||||||
|
echo
|
||||||
|
echo "Unpacking: ${PWD##*/}, using package..."
|
||||||
|
unpack "${pkg##*/}" "$pkg_sha"
|
||||||
|
}
|
||||||
|
|
||||||
|
elif [[ $git ]] && hash git 2>/dev/null; then
|
||||||
|
[[ -e .git ]] || {
|
||||||
|
echo
|
||||||
|
echo "Fetching: ${PWD##*/}, using git..."
|
||||||
|
git clone "$svn" .
|
||||||
|
printf '%s' "$(git describe --always)" > "${PWD##*/}-version"
|
||||||
|
}
|
||||||
|
|
||||||
|
elif [[ $svn ]] && hash git 2>/dev/null && [[ -x "$(git --exec-path)/git-svn" ]]; then
|
||||||
|
[[ -e .git ]] || {
|
||||||
|
echo
|
||||||
|
echo "Fetching: ${PWD##*/}, using git-svn..."
|
||||||
|
git svn clone --prefix=origin/ --stdlayout "$svn" .
|
||||||
|
printf '%s' "$(git describe --always)" > "${PWD##*/}-version"
|
||||||
|
}
|
||||||
|
|
||||||
|
elif [[ $svn ]] && hash svn 2>/dev/null; then
|
||||||
|
[[ -e .svn ]] || {
|
||||||
|
echo
|
||||||
|
echo "Fetching: ${PWD##*/}, using svn..."
|
||||||
|
svn checkout "$svn/trunk" .
|
||||||
|
printf 'r%s' "$(svn info | awk '/^Revision:/{ print $2 }')" > "${PWD##*/}-version"
|
||||||
|
}
|
||||||
|
|
||||||
|
elif [[ $pkg ]]; then
|
||||||
|
files=( !("${pkg##*/}") )
|
||||||
|
[[ -e $files ]] || {
|
||||||
|
echo
|
||||||
|
echo "Fetching: ${PWD##*/}, using package..."
|
||||||
|
fetch "$pkg"
|
||||||
|
unpack "${pkg##*/}" "$pkg_sha"
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
echo >&2 "error: Missing git-svn or svn."
|
||||||
|
echo >&2 "error: Please install either or manually check out the sources"
|
||||||
|
echo >&2 "error: from: $home"
|
||||||
|
echo >&2 "error: into: $PWD"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
)
|
||||||
|
depend() {
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "Checking dependency: $1..."
|
||||||
|
[[ -e "lib/$1/.built" ]] && return
|
||||||
|
|
||||||
|
pushd "lib/$1"
|
||||||
|
fetchSource
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "Configuring dependency: $1..."
|
||||||
|
if [[ -e configure.ac ]]; then
|
||||||
|
if [[ ! -e configure ]]; then
|
||||||
|
# create configure using autotools.
|
||||||
|
if ! hash aclocal || ! hash automake; then
|
||||||
|
echo >&2 "Need autotools to build $1. Please install automake and autoconf."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
aclocal
|
||||||
|
autoheader
|
||||||
|
autoconf
|
||||||
|
mkdir -p config.aux
|
||||||
|
automake --add-missing
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -e configure ]]; then
|
||||||
|
./configure
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "Building dependency: $1..."
|
||||||
|
if [[ -e Makefile ]]; then
|
||||||
|
if ! hash make; then
|
||||||
|
echo >&2 "Need make to build $1. Please install GNU make."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
make
|
||||||
|
date > .built
|
||||||
|
else
|
||||||
|
echo >&2 "error: Don't know how to build: $1"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
popd
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
### MPW
|
||||||
|
mpw() {
|
||||||
|
depend scrypt
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "Building target: $target..."
|
||||||
|
CFLAGS=(
|
||||||
|
# include paths
|
||||||
|
-I"lib/scrypt/lib" -I"lib/scrypt/libcperciva"
|
||||||
|
)
|
||||||
|
LDFLAGS=(
|
||||||
|
# library paths
|
||||||
|
-L"." -L"lib/scrypt"
|
||||||
|
# link libraries
|
||||||
|
-l"crypto"
|
||||||
|
# scrypt
|
||||||
|
"lib/scrypt/scrypt-crypto_aesctr.o"
|
||||||
|
"lib/scrypt/scrypt-sha256.o"
|
||||||
|
"lib/scrypt/scrypt-crypto_scrypt-nosse.o"
|
||||||
|
"lib/scrypt/scrypt-memlimit.o"
|
||||||
|
"lib/scrypt/scrypt-scryptenc_cpuperf.o"
|
||||||
|
"lib/scrypt/scrypt-scryptenc.o"
|
||||||
|
)
|
||||||
|
|
||||||
|
cc "${CFLAGS[@]}" -c types.c -o types.o "$@"
|
||||||
|
cc "${CFLAGS[@]}" "${LDFLAGS[@]}" "types.o" mpw.c -o mpw "$@"
|
||||||
|
echo "done! Now run ./install or use ./mpw"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
### MPW-BENCH
|
||||||
|
mpw-bench() {
|
||||||
|
depend scrypt
|
||||||
|
depend bcrypt
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "Building target: $target..."
|
||||||
|
CFLAGS=(
|
||||||
|
# include paths
|
||||||
|
-I"lib/scrypt/lib" -I"lib/scrypt/libcperciva"
|
||||||
|
-I"lib/bcrypt"
|
||||||
|
)
|
||||||
|
LDFLAGS=(
|
||||||
|
# library paths
|
||||||
|
-L"." -L"lib/scrypt"
|
||||||
|
-L"lib/bcrypt"
|
||||||
|
# libraries
|
||||||
|
-l"crypto"
|
||||||
|
# scrypt
|
||||||
|
"lib/scrypt/scrypt-crypto_aesctr.o"
|
||||||
|
"lib/scrypt/scrypt-sha256.o"
|
||||||
|
"lib/scrypt/scrypt-crypto_scrypt-nosse.o"
|
||||||
|
"lib/scrypt/scrypt-memlimit.o"
|
||||||
|
"lib/scrypt/scrypt-scryptenc_cpuperf.o"
|
||||||
|
"lib/scrypt/scrypt-scryptenc.o"
|
||||||
|
# bcrypt
|
||||||
|
"lib/bcrypt/crypt_blowfish.o"
|
||||||
|
"lib/bcrypt/crypt_gensalt.o"
|
||||||
|
"lib/bcrypt/wrapper.o"
|
||||||
|
"lib/bcrypt/x86.o"
|
||||||
|
)
|
||||||
|
|
||||||
|
cc "${CFLAGS[@]}" -c types.c -o types.o "$@"
|
||||||
|
cc "${CFLAGS[@]}" "${LDFLAGS[@]}" "types.o" mpw-bench.c -o mpw-bench "$@"
|
||||||
|
echo "done! Now use ./mpw-bench"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
### TARGETS
|
||||||
|
|
||||||
|
cc() {
|
||||||
|
if hash llvm-gcc 2>/dev/null; then
|
||||||
|
llvm-gcc "$@"
|
||||||
|
elif hash gcc 2>/dev/null; then
|
||||||
|
gcc -std=gnu99 "$@"
|
||||||
|
elif hash clang 2>/dev/null; then
|
||||||
|
clang "$@"
|
||||||
|
else
|
||||||
|
echo >&2 "Need a compiler. Please install GCC or LLVM."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "Will build targets: ${targets[*]}..."
|
||||||
|
for target in "${targets[@]}"; do
|
||||||
|
"$target" "$@"
|
||||||
|
done
|
||||||
|
|||||||
20
MasterPassword/C/distribute
Executable file
20
MasterPassword/C/distribute
Executable file
@@ -0,0 +1,20 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
cd "${BASH_SOURCE%/*}"
|
||||||
|
tag=$(git describe)
|
||||||
|
commit=$(git describe --long --dirty)
|
||||||
|
[[ $tag && $commit = $tag-* ]] || exit 1
|
||||||
|
git show --show-signature --pretty=format:%H --quiet "$tag" > VERSION
|
||||||
|
|
||||||
|
mpwArchive=mpw-$commit.tar.gz
|
||||||
|
[[ -e $mpwArchive ]] && echo "WARNING: $mpwArchive already exists. Will overwrite."
|
||||||
|
read -n1 -p "Will prepare and release $mpwArchive. Press a key to continue or ^C to abort."
|
||||||
|
|
||||||
|
git ls-files -z . | xargs -0 tar -cvzf "$mpwArchive"
|
||||||
|
echo "$mpwArchive ready, SHA256: $(openssl sha -sha256 < "$mpwArchive")"
|
||||||
|
|
||||||
|
cd ../../Site/current
|
||||||
|
ln -sf "../../MasterPassword/C/$mpwArchive"
|
||||||
|
[[ -e $_ ]]
|
||||||
|
echo "Linked from site, please update your hyperlinks to point to http://masterpasswordapp.com/$mpwArchive"
|
||||||
3
MasterPassword/C/lib/bcrypt/.source
Normal file
3
MasterPassword/C/lib/bcrypt/.source
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
home=http://www.openwall.com/crypt/
|
||||||
|
pkg=http://www.openwall.com/crypt/crypt_blowfish-1.3.tar.gz
|
||||||
|
pkg_sha=7253c86c8fe890e67ec782749f95ce3f1517b065
|
||||||
@@ -1 +1,4 @@
|
|||||||
https://code.google.com/p/scrypt/
|
home=https://code.google.com/p/scrypt/
|
||||||
|
svn=http://scrypt.googlecode.com/svn
|
||||||
|
pkg=http://masterpasswordapp.com/libscrypt-b12b554.tar.gz
|
||||||
|
pkg_sha=a86445c3e031392d20652f4163adfd3fb0b1994e
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
187
MasterPassword/C/mpw-bench.c
Normal file
187
MasterPassword/C/mpw-bench.c
Normal file
@@ -0,0 +1,187 @@
|
|||||||
|
#include <sys/time.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <alg/sha256.h>
|
||||||
|
#include <crypto/crypto_scrypt.h>
|
||||||
|
#include <ow-crypt.h>
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
#define MP_N 32768
|
||||||
|
#define MP_r 8
|
||||||
|
#define MP_p 2
|
||||||
|
#define MP_dkLen 64
|
||||||
|
#define MP_hash PearlHashSHA256
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char *const argv[]) {
|
||||||
|
|
||||||
|
char *userName = "Robert Lee Mitchel";
|
||||||
|
char *masterPassword = "banana colored duckling";
|
||||||
|
char *siteName = "masterpasswordapp.com";
|
||||||
|
uint32_t siteCounter = 1;
|
||||||
|
MPElementType siteType = MPElementTypeGeneratedLong;
|
||||||
|
|
||||||
|
// Start MP
|
||||||
|
struct timeval startTime;
|
||||||
|
if (gettimeofday(&startTime, NULL) != 0) {
|
||||||
|
fprintf(stderr, "Could not get time: %d\n", errno);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int iterations = 100;
|
||||||
|
for (int i = 0; i < iterations; ++i) {
|
||||||
|
// Calculate the master key salt.
|
||||||
|
char *mpNameSpace = "com.lyndir.masterpassword";
|
||||||
|
const uint32_t n_userNameLength = htonl(strlen(userName));
|
||||||
|
const size_t masterKeySaltLength = strlen(mpNameSpace) + sizeof(n_userNameLength) + strlen(userName);
|
||||||
|
char *masterKeySalt = malloc( masterKeySaltLength );
|
||||||
|
if (!masterKeySalt) {
|
||||||
|
fprintf(stderr, "Could not allocate master key salt: %d\n", errno);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *mKS = masterKeySalt;
|
||||||
|
memcpy(mKS, mpNameSpace, strlen(mpNameSpace)); mKS += strlen(mpNameSpace);
|
||||||
|
memcpy(mKS, &n_userNameLength, sizeof(n_userNameLength)); mKS += sizeof(n_userNameLength);
|
||||||
|
memcpy(mKS, userName, strlen(userName)); mKS += strlen(userName);
|
||||||
|
if (mKS - masterKeySalt != masterKeySaltLength)
|
||||||
|
abort();
|
||||||
|
trc("masterKeySalt ID: %s\n", IDForBuf(masterKeySalt, masterKeySaltLength));
|
||||||
|
|
||||||
|
// Calculate the master key.
|
||||||
|
uint8_t *masterKey = malloc( MP_dkLen );
|
||||||
|
if (!masterKey) {
|
||||||
|
fprintf(stderr, "Could not allocate master key: %d\n", errno);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
memset(masterKeySalt, 0, masterKeySaltLength);
|
||||||
|
free(masterKeySalt);
|
||||||
|
|
||||||
|
// Calculate the site seed.
|
||||||
|
const uint32_t n_siteNameLength = htonl(strlen(siteName));
|
||||||
|
const uint32_t n_siteCounter = htonl(siteCounter);
|
||||||
|
const size_t sitePasswordInfoLength = strlen(mpNameSpace) + sizeof(n_siteNameLength) + strlen(siteName) + sizeof(n_siteCounter);
|
||||||
|
char *sitePasswordInfo = malloc( sitePasswordInfoLength );
|
||||||
|
if (!sitePasswordInfo) {
|
||||||
|
fprintf(stderr, "Could not allocate site seed: %d\n", errno);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *sPI = sitePasswordInfo;
|
||||||
|
memcpy(sPI, mpNameSpace, strlen(mpNameSpace)); sPI += strlen(mpNameSpace);
|
||||||
|
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);
|
||||||
|
if (sPI - sitePasswordInfo != sitePasswordInfoLength)
|
||||||
|
abort();
|
||||||
|
|
||||||
|
uint8_t sitePasswordSeed[32];
|
||||||
|
HMAC_SHA256_Buf(masterKey, MP_dkLen, sitePasswordInfo, sitePasswordInfoLength, sitePasswordSeed);
|
||||||
|
memset(masterKey, 0, MP_dkLen);
|
||||||
|
memset(sitePasswordInfo, 0, sitePasswordInfoLength);
|
||||||
|
free(masterKey);
|
||||||
|
free(sitePasswordInfo);
|
||||||
|
|
||||||
|
// Determine the cipher.
|
||||||
|
const char *cipher = CipherForType(siteType, sitePasswordSeed[0]);
|
||||||
|
trc("type %d, cipher: %s\n", siteType, cipher);
|
||||||
|
if (strlen(cipher) > 32)
|
||||||
|
abort();
|
||||||
|
|
||||||
|
// Encode the password from the seed using the cipher.
|
||||||
|
char *sitePassword = calloc(strlen(cipher) + 1, sizeof(char));
|
||||||
|
for (int c = 0; c < strlen(cipher); ++c) {
|
||||||
|
sitePassword[c] = CharacterFromClass(cipher[c], sitePasswordSeed[c + 1]);
|
||||||
|
trc("class %c, character: %c\n", cipher[c], sitePassword[c]);
|
||||||
|
}
|
||||||
|
memset(sitePasswordSeed, 0, sizeof(sitePasswordSeed));
|
||||||
|
|
||||||
|
if (i % 1 == 0)
|
||||||
|
fprintf( stderr, "\rmpw: iteration %d / %d..", i, iterations );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output timing results.
|
||||||
|
struct timeval endTime;
|
||||||
|
if (gettimeofday(&endTime, NULL) != 0) {
|
||||||
|
fprintf(stderr, "Could not get time: %d\n", errno);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
long long secs = (endTime.tv_sec - startTime.tv_sec);
|
||||||
|
long long usecs = (endTime.tv_usec - startTime.tv_usec);
|
||||||
|
double elapsed = secs + usecs / 1000000.0;
|
||||||
|
double mpwSpeed = iterations / elapsed;
|
||||||
|
fprintf( stdout, " done. %d iterations in %llds %lldµs -> %.2f/s\n", iterations, secs, usecs, mpwSpeed );
|
||||||
|
|
||||||
|
// Start SHA-256
|
||||||
|
if (gettimeofday(&startTime, NULL) != 0) {
|
||||||
|
fprintf(stderr, "Could not get time: %d\n", errno);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
iterations = 50000000;
|
||||||
|
uint8_t hash[32];
|
||||||
|
for (int i = 0; i < iterations; ++i) {
|
||||||
|
SHA256_Buf(masterPassword, strlen(masterPassword), hash);
|
||||||
|
|
||||||
|
if (i % 1000 == 0)
|
||||||
|
fprintf( stderr, "\rsha256: iteration %d / %d..", i, iterations );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output timing results.
|
||||||
|
if (gettimeofday(&endTime, NULL) != 0) {
|
||||||
|
fprintf(stderr, "Could not get time: %d\n", errno);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
secs = (endTime.tv_sec - startTime.tv_sec);
|
||||||
|
usecs = (endTime.tv_usec - startTime.tv_usec);
|
||||||
|
elapsed = secs + usecs / 1000000.0;
|
||||||
|
double sha256Speed = iterations / elapsed;
|
||||||
|
fprintf( stdout, " done. %d iterations in %llds %lldµs -> %.2f/s\n", iterations, secs, usecs, sha256Speed );
|
||||||
|
|
||||||
|
// Start BCrypt
|
||||||
|
if (gettimeofday(&startTime, NULL) != 0) {
|
||||||
|
fprintf(stderr, "Could not get time: %d\n", errno);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bcrypt_cost = 9;
|
||||||
|
iterations = 600;
|
||||||
|
for (int i = 0; i < iterations; ++i) {
|
||||||
|
crypt(masterPassword, crypt_gensalt("$2b$", bcrypt_cost, userName, strlen(userName)));
|
||||||
|
|
||||||
|
if (i % 10 == 0)
|
||||||
|
fprintf( stderr, "\rbcrypt (cost %d): iteration %d / %d..", bcrypt_cost, i, iterations );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output timing results.
|
||||||
|
if (gettimeofday(&endTime, NULL) != 0) {
|
||||||
|
fprintf(stderr, "Could not get time: %d\n", errno);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
secs = (endTime.tv_sec - startTime.tv_sec);
|
||||||
|
usecs = (endTime.tv_usec - startTime.tv_usec);
|
||||||
|
elapsed = secs + usecs / 1000000.0;
|
||||||
|
double bcrypt9Speed = iterations / elapsed;
|
||||||
|
fprintf( stdout, " done. %d iterations in %llds %lldµs -> %.2f/s\n", iterations, secs, usecs, bcrypt9Speed );
|
||||||
|
|
||||||
|
// Summarize.
|
||||||
|
fprintf( stdout, "\n== SUMMARY ==\nOn this machine,\n" );
|
||||||
|
fprintf( stdout, "mpw is %f times slower than sha256\n", sha256Speed / mpwSpeed );
|
||||||
|
fprintf( stdout, "mpw is %f times slower than bcrypt (cost 9)\n", bcrypt9Speed / mpwSpeed );
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
#define _WITH_GETLINE
|
#define _GNU_SOURCE
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@@ -23,6 +24,12 @@
|
|||||||
#include <crypto/crypto_scrypt.h>
|
#include <crypto/crypto_scrypt.h>
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
|
#if defined(READLINE)
|
||||||
|
#include <readline/readline.h>
|
||||||
|
#elif defined(EDITLINE)
|
||||||
|
#include <histedit.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#define MP_N 32768
|
#define MP_N 32768
|
||||||
#define MP_r 8
|
#define MP_r 8
|
||||||
#define MP_p 2
|
#define MP_p 2
|
||||||
@@ -52,7 +59,14 @@ void usage() {
|
|||||||
fprintf(stderr, " -v variant The kind of content to generate.\n"
|
fprintf(stderr, " -v variant The kind of content to generate.\n"
|
||||||
" Defaults to 'password'.\n"
|
" Defaults to 'password'.\n"
|
||||||
" p, password | The password to log in with.\n"
|
" p, password | The password to log in with.\n"
|
||||||
" l, login | The username to log in as.\n\n");
|
" l, login | The username to log in as.\n"
|
||||||
|
" a, answer | The answer to a security question.\n\n");
|
||||||
|
fprintf(stderr, " -C context A variant-specific context.\n"
|
||||||
|
" Defaults to empty.\n"
|
||||||
|
" -v p, password | Doesn't currently use a context.\n"
|
||||||
|
" -v l, login | Doesn't currently use a context.\n"
|
||||||
|
" -v a, answer | Empty for a universal site answer or\n"
|
||||||
|
" | the most significant word(s) of the question.\n\n");
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,27 +108,30 @@ int main(int argc, char *const argv[]) {
|
|||||||
const char *siteTypeString = getenv( MP_env_sitetype );
|
const char *siteTypeString = getenv( MP_env_sitetype );
|
||||||
MPElementVariant siteVariant = MPElementVariantPassword;
|
MPElementVariant siteVariant = MPElementVariantPassword;
|
||||||
const char *siteVariantString = NULL;
|
const char *siteVariantString = NULL;
|
||||||
|
const char *siteContextString = NULL;
|
||||||
uint32_t siteCounter = 1;
|
uint32_t siteCounter = 1;
|
||||||
const char *siteCounterString = getenv( MP_env_sitecounter );
|
const char *siteCounterString = getenv( MP_env_sitecounter );
|
||||||
|
|
||||||
// Read the options.
|
// Read the options.
|
||||||
char opt;
|
for (int opt; (opt = getopt(argc, argv, "u:t:c:v:C:h")) != -1;)
|
||||||
while ((opt = getopt(argc, argv, "u:t:c:v:h")) != -1)
|
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'h':
|
|
||||||
usage();
|
|
||||||
break;
|
|
||||||
case 'u':
|
case 'u':
|
||||||
userName = optarg;
|
userName = optarg;
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
siteTypeString = optarg;
|
siteTypeString = optarg;
|
||||||
break;
|
break;
|
||||||
|
case 'c':
|
||||||
|
siteCounterString = optarg;
|
||||||
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
siteVariantString = optarg;
|
siteVariantString = optarg;
|
||||||
break;
|
break;
|
||||||
case 'c':
|
case 'C':
|
||||||
siteCounterString = optarg;
|
siteContextString = optarg;
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
usage();
|
||||||
break;
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
switch (optopt) {
|
switch (optopt) {
|
||||||
@@ -160,6 +177,8 @@ int main(int argc, char *const argv[]) {
|
|||||||
trc("siteVariant: %d (%s)\n", siteVariant, siteVariantString);
|
trc("siteVariant: %d (%s)\n", siteVariant, siteVariantString);
|
||||||
if (siteVariant == MPElementVariantLogin)
|
if (siteVariant == MPElementVariantLogin)
|
||||||
siteType = MPElementTypeGeneratedName;
|
siteType = MPElementTypeGeneratedName;
|
||||||
|
if (siteVariant == MPElementVariantAnswer)
|
||||||
|
siteType = MPElementTypeGeneratedPhrase;
|
||||||
if (siteTypeString)
|
if (siteTypeString)
|
||||||
siteType = TypeWithName( siteTypeString );
|
siteType = TypeWithName( siteTypeString );
|
||||||
trc("siteType: %d (%s)\n", siteType, siteTypeString);
|
trc("siteType: %d (%s)\n", siteType, siteTypeString);
|
||||||
@@ -172,31 +191,27 @@ int main(int argc, char *const argv[]) {
|
|||||||
}
|
}
|
||||||
trc("mpwConfigPath: %s\n", mpwConfigPath);
|
trc("mpwConfigPath: %s\n", mpwConfigPath);
|
||||||
FILE *mpwConfig = fopen(mpwConfigPath, "r");
|
FILE *mpwConfig = fopen(mpwConfigPath, "r");
|
||||||
if (!mpwConfig) {
|
|
||||||
fprintf(stderr, "Couldn't open configuration file: %s: %d\n", mpwConfigPath, errno);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
free(mpwConfigPath);
|
free(mpwConfigPath);
|
||||||
char *line = NULL;
|
if (mpwConfig) {
|
||||||
size_t linecap = 0;
|
char *line = NULL;
|
||||||
ssize_t linelen;
|
size_t linecap = 0;
|
||||||
while ((linelen = getline(&line, &linecap, mpwConfig)) > 0)
|
ssize_t linelen;
|
||||||
if (strcmp(strsep(&line, ":"), userName) == 0) {
|
while ((linelen = getline(&line, &linecap, mpwConfig)) > 0)
|
||||||
masterPassword = strsep(&line, "\n");
|
if (strcmp(strsep(&line, ":"), userName) == 0) {
|
||||||
break;
|
masterPassword = strsep(&line, "\n");
|
||||||
}
|
break;
|
||||||
if (!masterPassword) {
|
}
|
||||||
fprintf(stderr, "Missing master password for user: %s\n", userName);
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
while (!masterPassword)
|
||||||
|
masterPassword = getpass( "Your master password: " );
|
||||||
trc("masterPassword: %s\n", masterPassword);
|
trc("masterPassword: %s\n", masterPassword);
|
||||||
|
|
||||||
// Calculate the master key salt.
|
// Calculate the master key salt.
|
||||||
const char *mpKeyScope = ScopeForVariant(MPElementVariantPassword);
|
const char *mpKeyScope = ScopeForVariant(MPElementVariantPassword);
|
||||||
trc("key scope: %s\n", mpKeyScope);
|
trc("key scope: %s\n", mpKeyScope);
|
||||||
const uint32_t n_userNameLength = htonl(strlen(userName));
|
const uint32_t n_userNameLength = htonl(strlen(userName));
|
||||||
size_t masterKeySaltLength = strlen(mpKeyScope) + sizeof(n_userNameLength) + strlen(userName);
|
const size_t masterKeySaltLength = strlen(mpKeyScope) + sizeof(n_userNameLength) + strlen(userName);
|
||||||
char *masterKeySalt = malloc( masterKeySaltLength );
|
char *masterKeySalt = (char *)malloc( masterKeySaltLength );
|
||||||
if (!masterKeySalt) {
|
if (!masterKeySalt) {
|
||||||
fprintf(stderr, "Could not allocate master key salt: %d\n", errno);
|
fprintf(stderr, "Could not allocate master key salt: %d\n", errno);
|
||||||
return 1;
|
return 1;
|
||||||
@@ -211,7 +226,7 @@ int main(int argc, char *const argv[]) {
|
|||||||
trc("masterKeySalt ID: %s\n", IDForBuf(masterKeySalt, masterKeySaltLength));
|
trc("masterKeySalt ID: %s\n", IDForBuf(masterKeySalt, masterKeySaltLength));
|
||||||
|
|
||||||
// Calculate the master key.
|
// Calculate the master key.
|
||||||
uint8_t *masterKey = malloc( MP_dkLen );
|
uint8_t *masterKey = (uint8_t *)malloc( MP_dkLen );
|
||||||
if (!masterKey) {
|
if (!masterKey) {
|
||||||
fprintf(stderr, "Could not allocate master key: %d\n", errno);
|
fprintf(stderr, "Could not allocate master key: %d\n", errno);
|
||||||
return 1;
|
return 1;
|
||||||
@@ -228,11 +243,14 @@ int main(int argc, char *const argv[]) {
|
|||||||
|
|
||||||
// Calculate the site seed.
|
// Calculate the site seed.
|
||||||
const char *mpSiteScope = ScopeForVariant(siteVariant);
|
const char *mpSiteScope = ScopeForVariant(siteVariant);
|
||||||
trc("site scope: %s\n", mpSiteScope);
|
trc("site scope: %s, context: %s\n", mpSiteScope, siteContextString == NULL? "<empty>": siteContextString);
|
||||||
const uint32_t n_siteNameLength = htonl(strlen(siteName));
|
const uint32_t n_siteNameLength = htonl(strlen(siteName));
|
||||||
const uint32_t n_siteCounter = htonl(siteCounter);
|
const uint32_t n_siteCounter = htonl(siteCounter);
|
||||||
|
const uint32_t n_siteContextLength = siteContextString == NULL? 0: htonl(strlen(siteContextString));
|
||||||
size_t sitePasswordInfoLength = strlen(mpSiteScope) + sizeof(n_siteNameLength) + strlen(siteName) + sizeof(n_siteCounter);
|
size_t sitePasswordInfoLength = strlen(mpSiteScope) + sizeof(n_siteNameLength) + strlen(siteName) + sizeof(n_siteCounter);
|
||||||
char *sitePasswordInfo = malloc( sitePasswordInfoLength );
|
if (siteContextString)
|
||||||
|
sitePasswordInfoLength += sizeof(n_siteContextLength) + strlen(siteContextString);
|
||||||
|
char *sitePasswordInfo = (char *)malloc( sitePasswordInfoLength );
|
||||||
if (!sitePasswordInfo) {
|
if (!sitePasswordInfo) {
|
||||||
fprintf(stderr, "Could not allocate site seed: %d\n", errno);
|
fprintf(stderr, "Could not allocate site seed: %d\n", errno);
|
||||||
return 1;
|
return 1;
|
||||||
@@ -243,9 +261,13 @@ int main(int argc, char *const argv[]) {
|
|||||||
memcpy(sPI, &n_siteNameLength, sizeof(n_siteNameLength)); sPI += sizeof(n_siteNameLength);
|
memcpy(sPI, &n_siteNameLength, sizeof(n_siteNameLength)); sPI += sizeof(n_siteNameLength);
|
||||||
memcpy(sPI, siteName, strlen(siteName)); sPI += strlen(siteName);
|
memcpy(sPI, siteName, strlen(siteName)); sPI += strlen(siteName);
|
||||||
memcpy(sPI, &n_siteCounter, sizeof(n_siteCounter)); sPI += sizeof(n_siteCounter);
|
memcpy(sPI, &n_siteCounter, sizeof(n_siteCounter)); sPI += sizeof(n_siteCounter);
|
||||||
|
if (siteContextString) {
|
||||||
|
memcpy(sPI, &n_siteContextLength, sizeof(n_siteContextLength)); sPI += sizeof(n_siteContextLength);
|
||||||
|
memcpy(sPI, siteContextString, strlen(siteContextString)); sPI += strlen(siteContextString);
|
||||||
|
}
|
||||||
if (sPI - sitePasswordInfo != sitePasswordInfoLength)
|
if (sPI - sitePasswordInfo != sitePasswordInfoLength)
|
||||||
abort();
|
abort();
|
||||||
trc("seed from: hmac-sha256(masterKey, %s | %s | %s | %s)\n", mpSiteScope, Hex(&n_siteNameLength, sizeof(n_siteNameLength)), siteName, Hex(&n_siteCounter, sizeof(n_siteCounter)));
|
trc("seed from: hmac-sha256(masterKey, %s | %s | %s | %s | %s | %s)\n", mpSiteScope, Hex(&n_siteNameLength, sizeof(n_siteNameLength)), siteName, Hex(&n_siteCounter, sizeof(n_siteCounter)), Hex(&n_siteContextLength, sizeof(n_siteContextLength)), siteContextString);
|
||||||
trc("sitePasswordInfo ID: %s\n", IDForBuf(sitePasswordInfo, sitePasswordInfoLength));
|
trc("sitePasswordInfo ID: %s\n", IDForBuf(sitePasswordInfo, sitePasswordInfoLength));
|
||||||
|
|
||||||
uint8_t sitePasswordSeed[32];
|
uint8_t sitePasswordSeed[32];
|
||||||
@@ -263,7 +285,7 @@ int main(int argc, char *const argv[]) {
|
|||||||
abort();
|
abort();
|
||||||
|
|
||||||
// Encode the password from the seed using the cipher.
|
// Encode the password from the seed using the cipher.
|
||||||
char *sitePassword = calloc(strlen(cipher) + 1, sizeof(char));
|
char *sitePassword = (char *)calloc(strlen(cipher) + 1, sizeof(char));
|
||||||
for (int c = 0; c < strlen(cipher); ++c) {
|
for (int c = 0; c < strlen(cipher); ++c) {
|
||||||
sitePassword[c] = CharacterFromClass(cipher[c], sitePasswordSeed[c + 1]);
|
sitePassword[c] = CharacterFromClass(cipher[c], sitePasswordSeed[c + 1]);
|
||||||
trc("class %c, character: %c\n", cipher[c], sitePassword[c]);
|
trc("class %c, character: %c\n", cipher[c], sitePassword[c]);
|
||||||
|
|||||||
@@ -50,19 +50,19 @@ const char *CipherForType(MPElementType type, uint8_t seedByte) {
|
|||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case MPElementTypeGeneratedMaximum: {
|
case MPElementTypeGeneratedMaximum: {
|
||||||
char *ciphers[] = { "anoxxxxxxxxxxxxxxxxx", "axxxxxxxxxxxxxxxxxno" };
|
const char *ciphers[] = { "anoxxxxxxxxxxxxxxxxx", "axxxxxxxxxxxxxxxxxno" };
|
||||||
return ciphers[seedByte % 2];
|
return ciphers[seedByte % 2];
|
||||||
}
|
}
|
||||||
case MPElementTypeGeneratedLong: {
|
case MPElementTypeGeneratedLong: {
|
||||||
char *ciphers[] = { "CvcvnoCvcvCvcv", "CvcvCvcvnoCvcv", "CvcvCvcvCvcvno", "CvccnoCvcvCvcv", "CvccCvcvnoCvcv", "CvccCvcvCvcvno", "CvcvnoCvccCvcv", "CvcvCvccnoCvcv", "CvcvCvccCvcvno", "CvcvnoCvcvCvcc", "CvcvCvcvnoCvcc", "CvcvCvcvCvccno", "CvccnoCvccCvcv", "CvccCvccnoCvcv", "CvccCvccCvcvno", "CvcvnoCvccCvcc", "CvcvCvccnoCvcc", "CvcvCvccCvccno", "CvccnoCvcvCvcc", "CvccCvcvnoCvcc", "CvccCvcvCvccno" };
|
const char *ciphers[] = { "CvcvnoCvcvCvcv", "CvcvCvcvnoCvcv", "CvcvCvcvCvcvno", "CvccnoCvcvCvcv", "CvccCvcvnoCvcv", "CvccCvcvCvcvno", "CvcvnoCvccCvcv", "CvcvCvccnoCvcv", "CvcvCvccCvcvno", "CvcvnoCvcvCvcc", "CvcvCvcvnoCvcc", "CvcvCvcvCvccno", "CvccnoCvccCvcv", "CvccCvccnoCvcv", "CvccCvccCvcvno", "CvcvnoCvccCvcc", "CvcvCvccnoCvcc", "CvcvCvccCvccno", "CvccnoCvcvCvcc", "CvccCvcvnoCvcc", "CvccCvcvCvccno" };
|
||||||
return ciphers[seedByte % 21];
|
return ciphers[seedByte % 21];
|
||||||
}
|
}
|
||||||
case MPElementTypeGeneratedMedium: {
|
case MPElementTypeGeneratedMedium: {
|
||||||
char *ciphers[] = { "CvcnoCvc", "CvcCvcno" };
|
const char *ciphers[] = { "CvcnoCvc", "CvcCvcno" };
|
||||||
return ciphers[seedByte % 2];
|
return ciphers[seedByte % 2];
|
||||||
}
|
}
|
||||||
case MPElementTypeGeneratedBasic: {
|
case MPElementTypeGeneratedBasic: {
|
||||||
char *ciphers[] = { "aaanaaan", "aannaaan", "aaannaaa" };
|
const char *ciphers[] = { "aaanaaan", "aannaaan", "aaannaaa" };
|
||||||
return ciphers[seedByte % 3];
|
return ciphers[seedByte % 3];
|
||||||
}
|
}
|
||||||
case MPElementTypeGeneratedShort: {
|
case MPElementTypeGeneratedShort: {
|
||||||
@@ -75,7 +75,7 @@ const char *CipherForType(MPElementType type, uint8_t seedByte) {
|
|||||||
return "cvccvcvcv";
|
return "cvccvcvcv";
|
||||||
}
|
}
|
||||||
case MPElementTypeGeneratedPhrase: {
|
case MPElementTypeGeneratedPhrase: {
|
||||||
char *ciphers[] = { "cvcc cvc cvccvcv cvc", "cvc cvccvcvcv cvcv", "cv cvccv cvc cvcvccv" };
|
const char *ciphers[] = { "cvcc cvc cvccvcv cvc", "cvc cvccvcvcv cvcv", "cv cvccv cvc cvcvccv" };
|
||||||
return ciphers[seedByte % 3];
|
return ciphers[seedByte % 3];
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
@@ -95,6 +95,8 @@ const MPElementVariant VariantWithName(const char *variantName) {
|
|||||||
return MPElementVariantPassword;
|
return MPElementVariantPassword;
|
||||||
if (0 == strcmp(lowerVariantName, "l") || 0 == strcmp(lowerVariantName, "login"))
|
if (0 == strcmp(lowerVariantName, "l") || 0 == strcmp(lowerVariantName, "login"))
|
||||||
return MPElementVariantLogin;
|
return MPElementVariantLogin;
|
||||||
|
if (0 == strcmp(lowerVariantName, "a") || 0 == strcmp(lowerVariantName, "answer"))
|
||||||
|
return MPElementVariantAnswer;
|
||||||
|
|
||||||
fprintf(stderr, "Not a variant name: %s", lowerVariantName);
|
fprintf(stderr, "Not a variant name: %s", lowerVariantName);
|
||||||
abort();
|
abort();
|
||||||
@@ -108,6 +110,9 @@ const char *ScopeForVariant(MPElementVariant variant) {
|
|||||||
case MPElementVariantLogin: {
|
case MPElementVariantLogin: {
|
||||||
return "com.lyndir.masterpassword.login";
|
return "com.lyndir.masterpassword.login";
|
||||||
}
|
}
|
||||||
|
case MPElementVariantAnswer: {
|
||||||
|
return "com.lyndir.masterpassword.answer";
|
||||||
|
}
|
||||||
default: {
|
default: {
|
||||||
fprintf(stderr, "Unknown variant: %d", variant);
|
fprintf(stderr, "Unknown variant: %d", variant);
|
||||||
abort();
|
abort();
|
||||||
@@ -170,7 +175,7 @@ const char *IDForBuf(const void *buf, size_t length) {
|
|||||||
uint8_t hash[32];
|
uint8_t hash[32];
|
||||||
SHA256_Buf(buf, length, hash);
|
SHA256_Buf(buf, length, hash);
|
||||||
|
|
||||||
char *id = calloc(65, sizeof(char));
|
char *id = (char *)calloc(65, sizeof(char));
|
||||||
for (int kH = 0; kH < 32; kH++)
|
for (int kH = 0; kH < 32; kH++)
|
||||||
sprintf(&(id[kH * 2]), "%02X", hash[kH]);
|
sprintf(&(id[kH * 2]), "%02X", hash[kH]);
|
||||||
|
|
||||||
@@ -178,7 +183,7 @@ const char *IDForBuf(const void *buf, size_t length) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const char *Hex(const void *buf, size_t length) {
|
const char *Hex(const void *buf, size_t length) {
|
||||||
char *id = calloc(length*2+1, sizeof(char));
|
char *id = (char *)calloc(length*2+1, sizeof(char));
|
||||||
for (int kH = 0; kH < length; kH++)
|
for (int kH = 0; kH < length; kH++)
|
||||||
sprintf(&(id[kH * 2]), "%02X", ((const uint8_t*)buf)[kH]);
|
sprintf(&(id[kH * 2]), "%02X", ((const uint8_t*)buf)[kH]);
|
||||||
return id;
|
return id;
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ typedef enum {
|
|||||||
MPElementVariantPassword,
|
MPElementVariantPassword,
|
||||||
/** Generate the login name to log in as. */
|
/** Generate the login name to log in as. */
|
||||||
MPElementVariantLogin,
|
MPElementVariantLogin,
|
||||||
|
/** Generate the answer to a security question. */
|
||||||
|
MPElementVariantAnswer,
|
||||||
} MPElementVariant;
|
} MPElementVariant;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|||||||
@@ -516,7 +516,7 @@
|
|||||||
TimeToCrack timeToCrack;
|
TimeToCrack timeToCrack;
|
||||||
NSString *timeToCrackString = nil;
|
NSString *timeToCrackString = nil;
|
||||||
id<MPAlgorithm> algorithm = site.algorithm?: MPAlgorithmDefault;
|
id<MPAlgorithm> algorithm = site.algorithm?: MPAlgorithmDefault;
|
||||||
MPAttacker attackHardware = [[MPConfig get].siteAttacker unsignedIntegerValue];
|
MPAttacker attackHardware = [[MPConfig get].siteAttacker integerValue];
|
||||||
if ([algorithm timeToCrack:&timeToCrack passwordOfType:site.type byAttacker:attackHardware] ||
|
if ([algorithm timeToCrack:&timeToCrack passwordOfType:site.type byAttacker:attackHardware] ||
|
||||||
[algorithm timeToCrack:&timeToCrack passwordString:password byAttacker:attackHardware])
|
[algorithm timeToCrack:&timeToCrack passwordString:password byAttacker:attackHardware])
|
||||||
timeToCrackString = NSStringFromTimeToCrack( timeToCrack );
|
timeToCrackString = NSStringFromTimeToCrack( timeToCrack );
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ To see a site's password anyway, tap and hold your finger down for a while
|
|||||||
<integer>0</integer>
|
<integer>0</integer>
|
||||||
<integer>1</integer>
|
<integer>1</integer>
|
||||||
<integer>2</integer>
|
<integer>2</integer>
|
||||||
<string>3</string>
|
<integer>3</integer>
|
||||||
</array>
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
<dict>
|
<dict>
|
||||||
|
|||||||
Reference in New Issue
Block a user