/**
 * scryptenc_cpuperf(opps):
 * Estimate the number of salsa20/8 cores which can be executed per second,
 * and return the value via opps.
 */
int
scryptenc_cpuperf(double * opps)
{
	struct timespec st;
	double resd, diffd;
	uint64_t i = 0;

	/* Get the clock resolution. */
	if (getclockres(&resd))
		return (2);

#ifdef DEBUG
	fprintf(stderr, "Clock resolution is %f\n", resd);
#endif

	/* Loop until the clock ticks. */
	if (getclocktime(&st))
		return (2);
	do {
		/* Do an scrypt. */
		if (crypto_scrypt(NULL, 0, NULL, 0, 16, 1, 1, NULL, 0))
			return (3);

		/* Has the clock ticked? */
		if (getclockdiff(&st, &diffd))
			return (2);
		if (diffd > 0)
			break;
	} while (1);

	/* Could how many scryps we can do before the next tick. */
	if (getclocktime(&st))
		return (2);
	do {
		/* Do an scrypt. */
		if (crypto_scrypt(NULL, 0, NULL, 0, 128, 1, 1, NULL, 0))
			return (3);

		/* We invoked the salsa20/8 core 512 times. */
		i += 512;

		/* Check if we have looped for long enough. */
		if (getclockdiff(&st, &diffd))
			return (2);
		if (diffd > resd)
			break;
	} while (1);

#ifdef DEBUG
	fprintf(stderr, "%u salsa20/8 cores performed in %f seconds\n",
	    (uintmax_t)i, diffd);
#endif

	/* We can do approximately i salsa20/8 cores per diffd seconds. */
	*opps = i / diffd;
	return (0);
}
Beispiel #2
0
bool derive_kek(uint8_t *passwd, size_t len, kdfp *kdfp, uint8_t *kek, size_t klen) {
    uint8_t *salt = kdfp->salt;
    uint64_t N    = kdfp->N;
    uint64_t r    = kdfp->r;
    uint64_t p    = kdfp->p;
    return crypto_scrypt(passwd, len, salt, SALT_LEN, N, r, p, kek, klen) == 0;
}
Beispiel #3
0
    lj::Uuid Auth_method_password_hash::authenticate(const lj::bson::Node& data) const
    {
        const std::string login(lj::bson::as_string(data[k_login_field]));
        auto iter = credentials_by_login_.find(login);
        if (iter == credentials_by_login_.end())
        {
            // Deal with unknown login.
            lj::log::format<lj::Debug>("auth_local: User not found for %s.")
                    << login
                    << lj::log::end;
            throw logjam::User_not_found_exception(login);
        }
        const lj::bson::Node* stored_credential = (*iter).second;

        // Prepare scrypt inputs
        lj::log::format<lj::Debug>("auth_local: Calculating derived key.");
        const size_t password_length = data[k_password_field].size();
        const uint8_t* password = data[k_password_field].to_value();
        const size_t salt_length = stored_credential->nav(k_salt_field).size();
        const uint8_t* salt = stored_credential->nav(k_salt_field).to_value();

        // calculate the derived key.
        uint8_t derived_key[k_derived_key_length];
        crypto_scrypt(password,
                password_length,
                salt,
                salt_length,
                k_N,
                k_r,
                k_p,
                derived_key,
                k_derived_key_length);

        // Get the stored derived key.
        lj::bson::Binary_type bin_type = lj::bson::Binary_type::k_bin_generic;
        uint32_t check_key_length = 0;
        const uint8_t* check_key = lj::bson::as_binary(stored_credential->nav(k_password_field),
                &bin_type,
                &check_key_length);

        // Compare the two keys. Abort if they don't match.
        for (size_t h = 0; h < k_derived_key_length; ++h)
        {
            if (derived_key[h] != check_key[h])
            {
                lj::log::format<lj::Debug>(
                        "auth_local: Credentials did not match for %s.")
                        << login
                        << lj::log::end;
                throw logjam::User_not_found_exception(login);
            }
        }

        // Login successful, return the user object.
        lj::log::format<lj::Debug>("auth_local: Authenticated user %s.")
                << login
                << lj::log::end;
        return lj::bson::as_uuid(stored_credential->nav(k_id_field));
    }
Beispiel #4
0
data_chunk scrypt(data_slice data, data_slice salt, uint64_t N, uint32_t p,
    uint32_t r, size_t length)
{
    data_chunk output(length);
    const auto result = crypto_scrypt(data.data(), data.size(), salt.data(),
        salt.size(), N, r, p, output.data(), output.size());
    handle_script_result(result);
    return output;
}
Beispiel #5
0
int main(int argc, char *argv[])
{
    Cmd * c = NULL;
	void * buf = NULL;
    uint32_t buffer_limit = 131072; /* 128k */

	#ifdef _WIN32
		_setmode( _fileno( stdout ), _O_BINARY );
		_setmode( _fileno( stdin  ), _O_BINARY );
	#endif

    if (argc > 1) {
        buffer_limit = atol(argv[1]);
    }

    while (1) {
		c = read_cmd();
		if (c == NULL) {
			fprintf(stderr, "command read failed\n");
			exit(1);
		}

		if ((c->hdr.passwdlen > buffer_limit) || (c->hdr.saltlen > buffer_limit) || (c->hdr.buflen > buffer_limit)) {
			fprintf(stderr, "buffer limit exceeded\n");
			exit(1);
		}

		buf = calloc(1, c->hdr.buflen);
		if (buf == NULL) {
			fprintf(stderr, "buffer allocation for buf failed\n");
			exit(1);
		}

		if (crypto_scrypt((const uint8_t*)c->passwd, c->hdr.passwdlen,
						  (const uint8_t*)c->salt, c->hdr.saltlen,
						  c->hdr.N, c->hdr.r, c->hdr.p,
						  (uint8_t*)buf, c->hdr.buflen)) {
			fprintf(stderr, "crypto_scrypt failed\n");
			exit(1);
		}

		write_uint32(c->hdr.buflen);

		if (fwrite(buf, c->hdr.buflen, 1, stdout) != 1) {
			perror("fwrite buf");
			exit(1);
		}

		fflush(stdout);

		free(c);
		free(buf);

		c = NULL;
		buf = NULL;
	}
}
Beispiel #6
0
 void SCrypt::derive(void *destination, size_t size, const string &password) {
     _checkCallOnlyOnce();
     int errorcode = crypto_scrypt(reinterpret_cast<const uint8_t*>(password.c_str()), password.size(),
                                   reinterpret_cast<const uint8_t*>(_config.salt().data()), _config.salt().size(),
                                   _config.N(), _config.r(), _config.p(),
                                   static_cast<uint8_t*>(destination), size);
     if (errorcode != 0) {
         throw std::runtime_error("Error running scrypt key derivation.");
     }
 }
Beispiel #7
0
//
// This is the actual key derivation function.
// It is binary safe and is exposed to this module for
// access to the underlying key derivation function of Scrypt
//
unsigned int
ScryptHashFunction(const uint8_t* key, size_t keylen, const uint8_t *salt, size_t saltlen, uint64_t N, uint32_t r, uint32_t p,uint8_t *buf, size_t buflen) {
  int rc = crypto_scrypt(key, keylen, salt, saltlen, N, r, p, buf, buflen);
  unsigned int error = (rc == 0) ? 0 : 3;

  if (error && errno) {
    error |= (errno << 16);
  }

  return (error);
}
Beispiel #8
0
static int
scryptenc_setup(uint8_t header[96], uint8_t dk[64],
    const uint8_t * passwd, size_t passwdlen,
    size_t maxmem, double maxmemfrac, double maxtime)
{
	uint8_t salt[32];
	uint8_t hbuf[32];
	int logN;
	uint64_t N;
	uint32_t r;
	uint32_t p;
	SHA256_CTX ctx;
	uint8_t * key_hmac = &dk[32];
	HMAC_SHA256_CTX hctx;
	int rc;

	/* Pick values for N, r, p. */
	if ((rc = pickparams(maxmem, maxmemfrac, maxtime,
	    &logN, &r, &p)) != 0)
		return (rc);
	N = (uint64_t)(1) << logN;

	/* Get some salt. */
	if (crypto_entropy_read(salt, 32))
		return (4);

	/* Generate the derived keys. */
	if (crypto_scrypt(passwd, passwdlen, salt, 32, N, r, p, dk, 64))
		return (3);

	/* Construct the file header. */
	memcpy(header, "scrypt", 6);
	header[6] = 0;
	header[7] = logN;
	be32enc(&header[8], r);
	be32enc(&header[12], p);
	memcpy(&header[16], salt, 32);

	/* Add header checksum. */
	SHA256_Init(&ctx);
	SHA256_Update(&ctx, header, 48);
	SHA256_Final(hbuf, &ctx);
	memcpy(&header[48], hbuf, 16);

	/* Add header signature (used for verifying password). */
	HMAC_SHA256_Init(&hctx, key_hmac, 32);
	HMAC_SHA256_Update(&hctx, header, 64);
	HMAC_SHA256_Final(hbuf, &hctx);
	memcpy(&header[64], hbuf, 32);

	/* Success! */
	return (0);
}
Beispiel #9
0
static int
scryptdec_setup(const uint8_t header[96], uint8_t dk[64],
                const uint8_t * passwd, size_t passwdlen,
                size_t maxmem, double maxmemfrac, double maxtime, int verbose)
{
    uint8_t salt[32];
    uint8_t hbuf[32];
    int logN;
    uint32_t r;
    uint32_t p;
    uint64_t N;
    SHA256_CTX ctx;
    uint8_t * key_hmac = &dk[32];
    HMAC_SHA256_CTX hctx;
    int rc;

    /* Parse N, r, p, salt. */
    logN = header[7];
    r = be32dec(&header[8]);
    p = be32dec(&header[12]);
    memcpy(salt, &header[16], 32);

    /* Verify header checksum. */
    SHA256_Init(&ctx);
    SHA256_Update(&ctx, header, 48);
    SHA256_Final(hbuf, &ctx);
    if (memcmp(&header[48], hbuf, 16))
        return (7);

    /*
     * Check whether the provided parameters are valid and whether the
     * key derivation function can be computed within the allowed memory
     * and CPU time.
     */
    if ((rc = checkparams(maxmem, maxmemfrac, maxtime, logN, r, p,
                          verbose)) != 0)
        return (rc);

    /* Compute the derived keys. */
    N = (uint64_t)(1) << logN;
    if (crypto_scrypt(passwd, passwdlen, salt, 32, N, r, p, dk, 64))
        return (3);

    /* Check header signature (i.e., verify password). */
    HMAC_SHA256_Init(&hctx, key_hmac, 32);
    HMAC_SHA256_Update(&hctx, header, 64);
    HMAC_SHA256_Final(hbuf, &hctx);
    if (memcmp(hbuf, &header[64], 32))
        return (11);

    /* Success! */
    return (0);
}
Beispiel #10
0
Status
ScryptSnrp::hash(DataChunk &result, DataSlice data, size_t size) const
{
    DataChunk out(size);

    int rc = crypto_scrypt(data.data(), data.size(),
                           salt.data(), salt.size(), n, r, p, out.data(), size);
    if (rc)
        return ABC_ERROR(ABC_CC_ScryptError, "Error calculating Scrypt hash");

    result = std::move(out);
    return Status();
}
Beispiel #11
0
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) {

    uint8_t *key = malloc( keySize );
    if (!key)
        return NULL;

    if (crypto_scrypt( (const uint8_t *)secret, strlen( secret ), salt, saltSize, N, r, p, key, keySize ) < 0) {
        mpw_free( key, keySize );
        return NULL;
    }

    return key;
}
Beispiel #12
0
jbyteArray JNICALL scryptN(JNIEnv *env, jclass cls, jbyteArray passwd, jbyteArray salt,
    jint N, jint r, jint p, jint dkLen)
{

#ifdef ANDROID
  log_basic_info();
  log_params(env, passwd, salt, N, r, p, dkLen);
#endif

    jint Plen = (*env)->GetArrayLength(env, passwd);
    jint Slen = (*env)->GetArrayLength(env, salt);
    jbyte *P = (*env)->GetByteArrayElements(env, passwd, NULL);
    jbyte *S = (*env)->GetByteArrayElements(env, salt,   NULL);
    uint8_t *buf = malloc(sizeof(uint8_t) * dkLen);
    jbyteArray DK = NULL;

    if (P == NULL || S == NULL || buf == NULL) goto cleanup;

    if (crypto_scrypt((uint8_t *) P, Plen, (uint8_t *) S, Slen, N, r, p, buf, dkLen)) {
        jclass e = (*env)->FindClass(env, "java/lang/IllegalArgumentException");
        char *msg;
        switch (errno) {
            case EINVAL:
                msg = "N must be a power of 2 greater than 1";
                break;
            case EFBIG:
            case ENOMEM:
                msg = "Insufficient memory available";
                break;
            default:
                msg = "Memory allocation failed";
        }
        (*env)->ThrowNew(env, e, msg);
        goto cleanup;
    }

    DK = (*env)->NewByteArray(env, dkLen);
    if (DK == NULL) goto cleanup;

    (*env)->SetByteArrayRegion(env, DK, 0, dkLen, (jbyte *) buf);

  cleanup:

    if (P) (*env)->ReleaseByteArrayElements(env, passwd, P, JNI_ABORT);
    if (S) (*env)->ReleaseByteArrayElements(env, salt,   S, JNI_ABORT);
    if (buf) free(buf);

    return DK;
}
Beispiel #13
0
static int crypt_all(int *pcount, struct db_salt *salt)
{
	int count = *pcount;
	int index = 0;

#ifdef _OPENMP
#pragma omp parallel for
	for (index = 0; index < count; index++)
#endif
	{
		crypto_scrypt((unsigned char*)saved_key[index], strlen((char*)saved_key[index]),
				cur_salt->salt, strlen((char*)cur_salt->salt),
				(1ULL) << cur_salt->N, cur_salt->r,
				cur_salt->p, (unsigned char*)crypt_out[index],
				BINARY_SIZE);
	}
	return count;
}
Beispiel #14
0
std::vector<unsigned char> decrypt_bip38_ec(const std::vector<unsigned char> key,  const std::string& passwd)
{
    int i;
    uint8_t passfactor[PASSFACTOR_SIZE];

    memset(passfactor,0,PASSFACTOR_SIZE);

    const unsigned char * s_key = reinterpret_cast<const unsigned char*>(key.data());

    crypto_scrypt((const uint8_t *)passwd.c_str(), passwd.length(),
                   &s_key[3 + ADDRESSHASH_SIZE], OWNERSALT_SIZE,
                   16384, 8, 8, passfactor, PASSFACTOR_SIZE );

    // compute EC point (passpoint) using passfactor
    struct bp_key ec_point;
    if(!bp_key_init(&ec_point)) {
        fprintf(stderr,"%s","cannot init EC point key");
        exit(3);
    }
    if(!bp_key_secret_set(&ec_point,passfactor,PASSFACTOR_SIZE)) {
        fprintf(stderr,"%s","cannot set EC point from passfactor");
        exit(3);
    }

    // get the passpoint as bytes
    unsigned char * passpoint;
    size_t passpoint_len;

    if(!bp_pubkey_get(&ec_point,(unsigned char **)&passpoint,&passpoint_len)) {
        fprintf(stderr,"%s","cannot get pubkey for EC point");
        exit(4);
    }

    // now we need to decrypt seedb
    uint8_t encryptedpart2[16];
    memset(encryptedpart2,0,16);
    memcpy(encryptedpart2, &s_key[3 + ADDRESSHASH_SIZE + OWNERSALT_SIZE + 8], 16);

    uint8_t encryptedpart1[16];
    memset(encryptedpart1,0,16);
    memcpy(encryptedpart1, &s_key[3 + ADDRESSHASH_SIZE + OWNERSALT_SIZE], 8);

    unsigned char derived[DERIVED_SIZE];
    // get the encryption key for seedb using scrypt
    // with passpoint as the key, salt is addresshash+ownersalt
    unsigned char derived_scrypt_salt[ADDRESSHASH_SIZE + OWNERSALT_SIZE];
    memcpy(derived_scrypt_salt, &s_key[3], ADDRESSHASH_SIZE); // copy the addresshash
    memcpy(derived_scrypt_salt+ADDRESSHASH_SIZE, &s_key[3+ADDRESSHASH_SIZE], OWNERSALT_SIZE); // copy the ownersalt
    crypto_scrypt( passpoint, passpoint_len,
                   derived_scrypt_salt, ADDRESSHASH_SIZE+OWNERSALT_SIZE,
                   1024, 1, 1, derived, DERIVED_SIZE );

    //get decryption key
    unsigned char derivedhalf2[DERIVED_SIZE/2];
    memcpy(derivedhalf2, derived+(DERIVED_SIZE/2), DERIVED_SIZE/2);

    unsigned char iv[32];
    memset(iv,0,32);

    EVP_CIPHER_CTX d;
    EVP_CIPHER_CTX_init(&d);
    EVP_DecryptInit_ex(&d, EVP_aes_256_ecb(), NULL, derivedhalf2, iv);

    unsigned char unencryptedpart2[32];
    int decrypt_len;

    EVP_DecryptUpdate(&d, unencryptedpart2, &decrypt_len, encryptedpart2, 16);
    EVP_DecryptUpdate(&d, unencryptedpart2, &decrypt_len, encryptedpart2, 16);
    for(i=0; i<16; i++) {
        unencryptedpart2[i] ^= derived[i + 16];
    }
    unsigned char unencryptedpart1[32];
    memcpy(encryptedpart1+8, unencryptedpart2, 8);
    EVP_DecryptUpdate(&d, unencryptedpart1, &decrypt_len, encryptedpart1, 16);
    EVP_DecryptUpdate(&d, unencryptedpart1, &decrypt_len, encryptedpart1, 16);
    for(i=0; i<16; i++) {
        unencryptedpart1[i] ^= derived[i];
    }

    // recoved seedb
    unsigned char seedb[24];
    memcpy(seedb, unencryptedpart1, 16);
    memcpy(&(seedb[16]), &(unencryptedpart2[8]), 8);

    // turn seedb into factorb (factorb = SHA256(SHA256(seedb)))
    unsigned char factorb[32];
    bu_Hash(factorb, seedb, 24);

    // multiply by passfactor (ec_point_pub)
    const EC_GROUP * ec_group = EC_KEY_get0_group(ec_point.k);
    const EC_POINT * ec_point_pub = EC_KEY_get0_public_key(ec_point.k);
    BIGNUM * bn_passfactor = BN_bin2bn(passfactor,32,BN_new());
    BIGNUM * bn_factorb = BN_bin2bn(factorb,32,BN_new());
    BIGNUM * bn_res = BN_new();
    BIGNUM * bn_final = BN_new();
    BIGNUM * bn_n = BN_new();
    BN_CTX * ctx = BN_CTX_new();
    EC_GROUP_get_order(ec_group, bn_n, ctx);
    BN_mul(bn_res, bn_passfactor, bn_factorb, ctx);
    BN_mod(bn_final, bn_res, bn_n, ctx);

    unsigned char finalKey[32];
    memset(finalKey, 0, 32);
    int n = BN_bn2bin(bn_final, finalKey);

    BN_clear_free(bn_passfactor);
    BN_clear_free(bn_factorb);
    BN_clear_free(bn_res);
    BN_clear_free(bn_n);
    BN_clear_free(bn_final);

    printf("\n");
    print_hex((char *)finalKey, 32);
    printf("\n");

    std::vector<unsigned char> out;
    out.assign(finalKey, finalKey + 32);

    return out;
}
Beispiel #15
0
int
salsa20_init(salsa20_ctx_t *ctx, uchar_t *salt, int saltlen, uchar_t *pwd, int pwd_len,
	 uchar_t *nonce, int enc)
{
	struct timespec tp;
	uint64_t tv;
	uchar_t num[25];
	uchar_t IV[32];
	uchar_t *key = ctx->pkey;

#ifndef	_USE_PBK
	int logN;
	uint32_t r, p;
	uint64_t N;

	if (XSALSA20_CRYPTO_NONCEBYTES % 8) {
		log_msg(LOG_ERR, 0, "XSALSA20_CRYPTO_NONCEBYTES is not a multiple of 8!\n");
		return (-1);
	}
	pickparams(&logN, &r, &p);
	N = (uint64_t)(1) << logN;
	if (crypto_scrypt(pwd, pwd_len, salt, saltlen, N, r, p, key, ctx->keylen)) {
		log_msg(LOG_ERR, 0, "Scrypt failed\n");
		return (-1);
	}
#else
	rv = PKCS5_PBKDF2_HMAC(pwd, pwd_len, salt, saltlen, PBE_ROUNDS, EVP_sha256(),
			       ctx->keylen, key);
	if (rv != ctx->keylen) {
		log_msg(LOG_ERR, 0, "Key size is %d bytes - should be %d bits\n", i, ctx->keylen);
		return (-1);
	}
#endif

	/*
	 * Copy the key. XSalsa20 core cipher always uses a 256-bit key. If we are using a
	 * 128-bit key then the key value is repeated twice to form a 256-bit value.
	 * This approach is based on the Salsa20 code submitted to eSTREAM. See the function
	 * ECRYPT_keysetup() in the Salsa20 submission:
	 * http://www.ecrypt.eu.org/stream/svn/viewcvs.cgi/ecrypt/trunk/submissions/salsa20/full/ref/salsa20.c?rev=161&view=auto
	 * 
	 * The input values corresponding to a 256-bit key contain repeated values if key
	 * length is 128-bit.
	 */
	memcpy(ctx->key, key, ctx->keylen);
	if (ctx->keylen < XSALSA20_CRYPTO_KEYBYTES) {
		uchar_t *k;
		k = ctx->key + ctx->keylen;
		memcpy(k, key, XSALSA20_CRYPTO_KEYBYTES - ctx->keylen);
	}

	if (enc) {
		int i;
		uint64_t *n, *n1;

		// Derive 192-bit nonce
		if (RAND_status() != 1 || RAND_bytes(IV, XSALSA20_CRYPTO_NONCEBYTES) != 1) {
			if (geturandom_bytes(IV, XSALSA20_CRYPTO_NONCEBYTES) != 0) {
				if (clock_gettime(CLOCK_MONOTONIC, &tp) == -1) {
					time((time_t *)&tv);
				} else {
					tv = tp.tv_sec * 1000UL + tp.tv_nsec;
				}
				sprintf((char *)num, "%" PRIu64, tv);
				PKCS5_PBKDF2_HMAC((const char *)num, strlen((char *)num), salt,
						saltlen, PBE_ROUNDS, EVP_sha256(), 32, IV);
			}
		}
		n = (uint64_t *)IV;
		n1 = (uint64_t *)(ctx->nonce);
		for (i = 0; i < XSALSA20_CRYPTO_NONCEBYTES/8; i++) {
			*n1 = LE64(*n);
			n++;
			n1++;
		}

		// Nullify stack components
		memset(num, 0, 25);
		memset(IV, 0, 32);
		memset(&tp, 0, sizeof (tp));
		tv = 0;
	} else {
		memcpy(ctx->nonce, nonce, XSALSA20_CRYPTO_NONCEBYTES);
		memset(nonce, 0, XSALSA20_CRYPTO_NONCEBYTES);
	}
	return (0);
}
Beispiel #16
0
int
main(int argc, char* argv[])
{
	char * passwd;
  uint64_t N = 1 << 14;
  uint32_t r = 8;
  uint32_t p = 1;
  char buf[65];
  size_t buflen = 64;
  int result;
  int i = 0;
  int punctuation = 1; // Whether to allow punctuation in the output
  int addbang = 0; // The the first character '!'
  int addfive = 0; // Make the 5th character '5'
  int length = 10; // Desired password length

  if (argc < 2) {
    usage();
  }

  // Disable punctuation in output for sites that are jerks
  if (strcmp(argv[1], "chase.com") == 0 ||
      strcmp(argv[1], "fandango.com") == 0 ||
      //strcmp(argv[1], "apple.com") == 0 ||
      strcmp(argv[1], "comcast.com") == 0 ||
      strcmp(argv[1], "verizonwireless.com") == 0 ||
      strcmp(argv[1], "gap.com") == 0 ||
      strcmp(argv[1], "audible.com") == 0 ||
      strcmp(argv[1], "purpletie.com") == 0 ||
      strcmp(argv[1], "opentable.com") == 0 ||
      strcmp(argv[1], "videoeta.com") == 0 ||
      strcmp(argv[1], "topcoder.com") == 0 ||
      strcmp(argv[1], "hondafinancialservices.com") == 0 ||
      strcmp(argv[1], "americanexpress.com") == 0 ||
      argc == 3) {
    punctuation = 0;
  }
  else if (strcmp(argv[1], "kaiserpermanente.org") == 0) {
    addbang = 1;
  }
  else if (strcmp(argv[1], "schwab.com") == 0) {
    // Schwab may have the stupidest password requirements I've ever
    // encountered.
    length = 8;
    addfive = 1;
    punctuation = 0;
  }
  else if (strcmp(argv[1], "deltadentalins.com") == 0 ||
           strcmp(argv[1], "mozilla.org") == 0 ||
           strcmp(argv[1], "morganstanleysmithbarney.com") == 0) {
    addfive = 1;
  }

	/* Prompt for a password. */
	if (tarsnap_readpass(&passwd, "Please enter passphrase", NULL, 1)) {
		exit(1);
  }

  result = crypto_scrypt(passwd, strlen(passwd), argv[1], strlen(argv[1]), N, r,
                         p, buf, buflen);
  buf[64] = 0;

  if (result != 0) {
    fprintf(stderr, "Something went wrong!\n");
    print_error(errno);
    exit(1);
  } else {
    print_it(buf, punctuation, addbang, length, addfive);
    printf("\n");
  }

	/* Zero and free the password. */
	memset(passwd, 0, strlen(passwd));
	free(passwd);

  return 0;
}
Beispiel #17
0
    void Auth_method_password_hash::change_credential(const lj::Uuid& target,
            const lj::bson::Node& data)
    {
        lj::log::format<lj::Debug>("auth_local: Finding existing user for %s")
                << target
                << lj::log::end;
        auto iter = credentials_by_id_.find(target);

        lj::bson::Node* stored_credential;
        if (credentials_by_id_.end() == iter)
        {
            lj::log::out<lj::Debug>(
                    "auth_local: No user found. creating record.");
            stored_credential = new lj::bson::Node();
            uint8_t temp_dk[1] = {0};
            stored_credential->set_child(k_id_field,
                    lj::bson::new_uuid(target));
            stored_credential->set_child(k_login_field,
                    lj::bson::new_string(""));
            stored_credential->set_child(k_password_field,
                    lj::bson::new_binary(temp_dk, 1, lj::bson::Binary_type::k_bin_generic));
            stored_credential->set_child(k_salt_field,
                    lj::bson::new_binary(temp_dk, 1, lj::bson::Binary_type::k_bin_generic));
            credentials_by_id_[target] = stored_credential;
        }
        else
        {
            stored_credential = (*iter).second;
        }

        lj::log::out<lj::Debug>("auth_local: calculating new derived key.");
        // read a new random salt.
        // TODO this is insecure. should use something much more secure
        // for creating salts.
        uint8_t salt_buffer[128];
        for (int h = 0; h < 128; ++h)
        {
            salt_buffer[h] = (rand() & 0xFF);
        }
        lj::bson::Node* salt_node = lj::bson::new_binary(
                salt_buffer,
                128,
                lj::bson::Binary_type::k_bin_generic);

        // The salt and password include the bson header info. This is
        // intentional, because it reduces the code complexity.
        const size_t salt_length = salt_node->size();
        const uint8_t* salt = salt_node->to_value();
        const size_t password_length = data[k_password_field].size();
        const uint8_t* password = data[k_password_field].to_value();

        // calculate the derived key.
        uint8_t derived_key[k_derived_key_length];
        crypto_scrypt(password,
                password_length,
                salt,
                salt_length,
                k_N,
                k_r,
                k_p,
                derived_key,
                k_derived_key_length);

        // check if there is an old record to remove.
        if (credentials_by_id_.end() != iter)
        {
            const std::string old_login(
                    lj::bson::as_string(stored_credential->nav(k_login_field)));
            lj::log::format<lj::Debug>("auth_local: Removing old record for %s / %s")
                    << old_login
                    << target
                    << lj::log::end;
            credentials_by_login_.erase(old_login);
        }

        // In theory, the user cannot log in during this point. There is no entry in the
        // users_by_credential_ to look up this user.

        // TODO Existing sessions should probably be disconnected here.

        // Record the new credential and mapping.
        const std::string new_login(lj::bson::as_string(data[k_login_field]));
        lj::log::format<lj::Debug>("auth_local: Creating new record for %s / %s")
                << new_login
                << target
                << lj::log::end;

        stored_credential->set_child(k_login_field,
                lj::bson::new_string(new_login));
        stored_credential->set_child(k_password_field,
                lj::bson::new_binary(derived_key,
                        k_derived_key_length,
                        lj::bson::Binary_type::k_bin_generic));
        stored_credential->set_child(k_salt_field,
                salt_node);

        credentials_by_login_[new_login] = stored_credential;
    }
Beispiel #18
0
std::vector<unsigned char> decrypt_bip38(const std::vector<unsigned char> enc_data,  const std::string& passwd)
{
	//def decrypt(encrypted_privkey, passphrase, p):
	//
	//#1. Collect encrypted private key and passphrase from user.
	//#	passed as parameters
    const unsigned char *data = reinterpret_cast<const unsigned char*>(enc_data.data());

    unsigned char key[64];
    unsigned char addresshash[4];
    unsigned char encryptedhalf1[16], encryptedhalf2[16];
    unsigned char decryptedhalf1[16], decryptedhalf2[16];
    unsigned char derivedhalf1[32], derivedhalf2[32];

	memcpy(addresshash, &data[3], 4);
	memcpy(encryptedhalf1, &data[7], 16);
	memcpy(encryptedhalf2, &data[23], 16);

	//#3. Derive decryption key for seedb using scrypt with passpoint, addresshash, and ownersalt
	//key = scrypt.hash(passphrase, addresshash, 16384, 8, p)
    crypto_scrypt((const uint8_t *)passwd.c_str(), passwd.length(),
                   &addresshash[0], ADDRESSHASH_SIZE, 16384, 8, 8, key, 64);

	memcpy(derivedhalf1, &key[0], 32);
	memcpy(derivedhalf2, &key[32], 32);
	//
	//#4. Decrypt encryptedpart2 using AES256Decrypt to yield the last 8 bytes of seedb and the last 8 bytes of encryptedpart1.
	//Aes = aes.Aes(derivedhalf2)
	//decryptedhalf2 = Aes.dec(encryptedhalf2)

    int decrypt_len;
    EVP_CIPHER_CTX de;

    EVP_CIPHER_CTX_init(&de);
    EVP_DecryptInit_ex(&de, EVP_aes_256_cbc(), NULL, derivedhalf2, NULL);
    EVP_DecryptUpdate(&de, decryptedhalf2, &decrypt_len, encryptedhalf2, 16);

	//#5. Decrypt encryptedpart1 to yield the remainder of seedb.
	//decryptedhalf1 = Aes.dec(encryptedhalf1)
    EVP_DecryptInit_ex(&de, EVP_aes_256_cbc(), NULL, derivedhalf2, NULL);
    EVP_DecryptUpdate(&de, decryptedhalf1, &decrypt_len, encryptedhalf1, 16);

	//priv = decryptedhalf1 + decryptedhalf2
	//priv = binascii.unhexlify('%064x' % (long(binascii.hexlify(priv), 16) ^ long(binascii.hexlify(derivedhalf1), 16)))
	//return priv, addresshash

    unsigned char priv[32];
    memcpy(priv, decryptedhalf1, 16);
    memcpy(priv + 16, decryptedhalf2, 16);

    for (int i = 0; i < 32; i++) {
    	priv[i] ^= derivedhalf1[i];
    }

//    printf("\n");
//    print_hex((char *)priv, 32);
//    printf("\n");

    std::vector<unsigned char> out;
    out.assign(priv, priv + 32);

    return out;
}
Beispiel #19
0
std::vector<unsigned char> encrypt_bip38(const std::vector<unsigned char> priv_key,
		const std::string& address, const std::string& passwd)
{
    unsigned char key[64];
    unsigned char derivedhalf1[32], derivedhalf2[32];
    unsigned char encryptedhalf1[16], encryptedhalf2[16];
    unsigned char part1[32], part2[32];

    const unsigned char * p_address = reinterpret_cast<const unsigned char*>(address.data());
    const unsigned char * p_secret = reinterpret_cast<const unsigned char*>(priv_key.data());

	// 1. take the first four bytes of SHA256(SHA256()) of it. Let's call this "addresshash".
    //		addresshash = hashlib.sha256(hashlib.sha256(address).digest()).digest()[:4]  # salt
    unsigned char addresshash[32];
    bu_Hash(addresshash, &p_address[0], 34);

    //		#2. Derive a key from the passphrase using scrypt
    //		#	 a.  Parameters: passphrase is the passphrase itself encoded in UTF-8.
    //		#		 addresshash came from the earlier step, n=16384, r=8, p=8, length=64
    //		#		 (n, r, p are provisional and subject to consensus)
    //		key = scrypt.hash(passphrase, addresshash, 16384, 8, p)
    crypto_scrypt((const uint8_t *)passwd.c_str(), passwd.length(),
                   &addresshash[0], ADDRESSHASH_SIZE, 16384, 8, 8, key, 64);

    memcpy(derivedhalf1, &key[0], 32);
    memcpy(derivedhalf2, &key[32], 32);

    //		#3. Do AES256Encrypt(bitcoinprivkey[0...15] xor derivedhalf1[0...15], derivedhalf2), call the 16-byte result encryptedhalf1
    //		Aes = aes.Aes(derivedhalf2)
    //		encryptedhalf1 = Aes.enc(enc.sxor(privK[:16], derivedhalf1[:16]))
    //

	for (int i=0; i < 16; i++)
		part1[i] = p_secret[i] ^ derivedhalf1[i];

	for (int i=0; i < 16; i++)
		part2[i] = p_secret[i + 16] ^ derivedhalf1[i + 16];

    int encrypt_len;
    EVP_CIPHER_CTX en;

    EVP_CIPHER_CTX_init(&en);
    EVP_EncryptInit_ex(&en, EVP_aes_256_cbc(), NULL, derivedhalf2, NULL);
    EVP_EncryptUpdate(&en, encryptedhalf1, &encrypt_len, part1, 16);
    EVP_EncryptInit_ex(&en, EVP_aes_256_cbc(), NULL, derivedhalf2, NULL);
    EVP_EncryptUpdate(&en, encryptedhalf2, &encrypt_len, part2, 16);

	//		#5. The encrypted private key is the Base58Check-encoded concatenation of the following, which totals 39 bytes without Base58 checksum:
	//		#		0x01 0x42 + flagbyte + salt + encryptedhalf1 + encryptedhalf2
	//		flagbyte = chr(0b11100000)  # 11 no-ec 1 compressed-pub 00 future 0 ec only 00 future
	//		privkey = ('\x01\x42' + flagbyte + addresshash + encryptedhalf1 + encryptedhalf2)
	//		check = hashlib.sha256(hashlib.sha256(privkey).digest()).digest()[:4]
	//		return enc.b58encode(privkey + check)

	unsigned char flagbyte = 0xc0;// 0b11100000; // 11 no-ec 1 compressed-pub 00 future 0 ec only 00 future
	unsigned char pref1 = 0x01;
	unsigned char pref2 = 0x42;

	unsigned char enc_key[128];
	enc_key[0] = pref1;
	enc_key[1] = pref2;
	enc_key[2] = flagbyte;

	memcpy(enc_key + 3, addresshash, ADDRESSHASH_SIZE);
	memcpy(enc_key + 3 + ADDRESSHASH_SIZE, encryptedhalf1, 16);
	memcpy(enc_key + 3 + ADDRESSHASH_SIZE + 16, encryptedhalf2, 16);

	return std::vector<unsigned char>(&enc_key[0], &enc_key[3 + ADDRESSHASH_SIZE + 32]);
}