Пример #1
0
static inline bool authValid(Dict* message, uint8_t* buffer, uint32_t length, struct Admin* admin)
{
    String* cookieStr = Dict_getString(message, String_CONST("cookie"));
    uint32_t cookie = (cookieStr != NULL) ? strtoll(cookieStr->bytes, NULL, 10) : 0;
    if (!cookie) {
        int64_t* cookieInt = Dict_getInt(message, String_CONST("cookie"));
        cookie = (cookieInt) ? *cookieInt : 0;
    }
    uint64_t nowSecs = Time_currentTimeSeconds(admin->eventBase);
    String* submittedHash = Dict_getString(message, String_CONST("hash"));
    if (cookie >  nowSecs || cookie < nowSecs - 20 || !submittedHash || submittedHash->len != 64) {
        return false;
    }

    uint8_t* hashPtr = (uint8_t*) strstr((char*) buffer, submittedHash->bytes);

    if (!hashPtr || !admin->password) {
        return false;
    }

    uint8_t passAndCookie[64];
    snprintf((char*) passAndCookie, 64, "%s%u", admin->password->bytes, cookie);
    uint8_t hash[32];
    crypto_hash_sha256(hash, passAndCookie, strlen((char*) passAndCookie));
    Hex_encode(hashPtr, 64, hash, 32);

    crypto_hash_sha256(hash, buffer, length);
    Hex_encode(hashPtr, 64, hash, 32);
    return memcmp(hashPtr, submittedHash->bytes, 64) == 0;
}
Пример #2
0
static int calculateAuth(Dict* message,
                         String* password,
                         String* cookieStr,
                         struct Allocator* alloc)
{
    // Calculate the hash of the password.
    String* hashHex = String_newBinary(NULL, 64, alloc);
    uint8_t passAndCookie[64];
    uint32_t cookie = (cookieStr != NULL) ? strtoll(cookieStr->bytes, NULL, 10) : 0;
    snprintf((char*) passAndCookie, 64, "%s%u", password->bytes, cookie);
    uint8_t hash[32];
    crypto_hash_sha256(hash, passAndCookie, strlen((char*) passAndCookie));
    Hex_encode((uint8_t*)hashHex->bytes, 64, hash, 32);

    Dict_putString(message, String_new("hash", alloc), hashHex, alloc);
    Dict_putString(message, String_new("cookie", alloc), cookieStr, alloc);

    // serialize the message with the password hash
    uint8_t buffer[AdminClient_MAX_MESSAGE_SIZE];
    struct Writer* writer = ArrayWriter_new(buffer, AdminClient_MAX_MESSAGE_SIZE, alloc);
    if (StandardBencSerializer_get()->serializeDictionary(writer, message)) {
        return -1;
    }
    int length = writer->bytesWritten;

    // calculate the hash of the message with the password hash
    crypto_hash_sha256(hash, buffer, length);

    // swap the hash of the message with the password hash into the location
    // where the password hash was.
    Hex_encode((uint8_t*)hashHex->bytes, 64, hash, 32);
    return 0;
}
Пример #3
0
static int calculateAuth(Dict* message,
                         String* password,
                         String* cookieStr,
                         struct Allocator* alloc)
{
    // Calculate the hash of the password.
    String* hashHex = String_newBinary(NULL, 64, alloc);
    uint8_t passAndCookie[64];
    uint32_t cookie = (cookieStr != NULL) ? strtoll(cookieStr->bytes, NULL, 10) : 0;
    snprintf((char*) passAndCookie, 64, "%s%u", password->bytes, cookie);
    uint8_t hash[32];
    crypto_hash_sha256(hash, passAndCookie, CString_strlen((char*) passAndCookie));
    Hex_encode((uint8_t*)hashHex->bytes, 64, hash, 32);

    Dict_putString(message, String_new("hash", alloc), hashHex, alloc);
    Dict_putString(message, String_new("cookie", alloc), cookieStr, alloc);

    // serialize the message with the password hash
    struct Message* msg = Message_new(0, AdminClient_MAX_MESSAGE_SIZE, alloc);
    BencMessageWriter_write(message, msg, NULL);

    // calculate the hash of the message with the password hash
    crypto_hash_sha256(hash, msg->bytes, msg->length);

    // swap the hash of the message with the password hash into the location
    // where the password hash was.
    Hex_encode((uint8_t*)hashHex->bytes, 64, hash, 32);
    return 0;
}
Пример #4
0
Auth::Auth(const char *passphrase)
{
    this->passphrase = passphrase;

    //TODO evalute this for better keystreching
    crypto_hash_sha256(this->encryptionkey, (const unsigned char*)passphrase, this->passphrase.length());
    for (int i=0;i<65535;++i)
        crypto_hash_sha256(this->encryptionkey, (const unsigned char*)this->encryptionkey, crypto_hash_sha256_BYTES);
}
Пример #5
0
static inline void hashPassword_sha256(struct Auth* auth, const String* password)
{
    uint8_t tempBuff[32];
    crypto_hash_sha256(auth->secret, (uint8_t*) password->bytes, password->len);
    crypto_hash_sha256(tempBuff, auth->secret, 32);
    memcpy(auth->challenge.bytes, tempBuff, Headers_AuthChallenge_SIZE);
    Headers_setAuthChallengeDerivations(&auth->challenge, 0);
    auth->challenge.challenge.type = 1;
}
Пример #6
0
static inline void getPasswordHash(uint8_t output[32], uint8_t derivations, struct Auth* auth)
{
    uint8_t tempBuff[32];
    memcpy(output, auth->secret, 32);
    for (uint32_t i = 0; i < derivations; i++) {
        crypto_hash_sha256(tempBuff, output, 32);
        crypto_hash_sha256(output, tempBuff, 32);
    }
}
Пример #7
0
/* Same as above, except with use the given salt for deterministic key derivation.
 * The salt must be TOX_PASS_SALT_LENGTH bytes in length.
 */
bool tox_pass_key_derive_with_salt(Tox_Pass_Key *out_key, const uint8_t *passphrase, size_t pplength,
                                   const uint8_t *salt, TOX_ERR_KEY_DERIVATION *error)
{
    if (!salt || !out_key || (!passphrase && pplength != 0)) {
        SET_ERROR_PARAMETER(error, TOX_ERR_KEY_DERIVATION_NULL);
        return 0;
    }

    uint8_t passkey[crypto_hash_sha256_BYTES];
    crypto_hash_sha256(passkey, passphrase, pplength);

    uint8_t key[CRYPTO_SHARED_KEY_SIZE];

    /* Derive a key from the password */
    /* http://doc.libsodium.org/key_derivation/README.html */
    /* note that, according to the documentation, a generic pwhash interface will be created
     * once the pwhash competition (https://password-hashing.net/) is over */
    if (crypto_pwhash_scryptsalsa208sha256(
                key, sizeof(key), (char *)passkey, sizeof(passkey), salt,
                crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE * 2, /* slightly stronger */
                crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE) != 0) {
        /* out of memory most likely */
        SET_ERROR_PARAMETER(error, TOX_ERR_KEY_DERIVATION_FAILED);
        return 0;
    }

    sodium_memzero(passkey, crypto_hash_sha256_BYTES); /* wipe plaintext pw */
    memcpy(out_key->salt, salt, crypto_pwhash_scryptsalsa208sha256_SALTBYTES);
    memcpy(out_key->key, key, CRYPTO_SHARED_KEY_SIZE);
    SET_ERROR_PARAMETER(error, TOX_ERR_KEY_DERIVATION_OK);
    return 1;
}
Пример #8
0
/**
 * Get a shared secret.
 *
 * @param outputSecret an array to place the shared secret in.
 * @param myPrivateKey
 * @param herPublicKey
 * @param logger
 * @param passwordHash a 32 byte value known to both ends, this must be provably pseudorandom
 *                     the first 32 bytes of a sha256 output from hashing a password is ok,
 *                     whatever she happens to send me in the Auth field is NOT ok.
 *                     If this field is null, the secret will be generated without the password.
 */
static inline void getSharedSecret(uint8_t outputSecret[32],
                                   uint8_t myPrivateKey[32],
                                   uint8_t herPublicKey[32],
                                   uint8_t passwordHash[32],
                                   struct Log* logger)
{
    uint8_t tempBuff[64];
    crypto_scalarmult_curve25519(tempBuff, myPrivateKey, herPublicKey);
    if (passwordHash == NULL) {
        crypto_core_hsalsa20(outputSecret, keyHashNonce, tempBuff, keyHashSigma);
    } else {
        memcpy(&tempBuff[32], passwordHash, 32);
        crypto_hash_sha256(outputSecret, tempBuff, 64);
    }
    #ifdef Log_KEYS
        uint8_t myPublicKeyHex[65];
        printHexPubKey(myPublicKeyHex, myPrivateKey);
        uint8_t herPublicKeyHex[65];
        printHexKey(herPublicKeyHex, herPublicKey);
        uint8_t passwordHashHex[65];
        printHexKey(passwordHashHex, passwordHash);
        uint8_t outputSecretHex[65] = "NULL";
        printHexKey(outputSecretHex, outputSecret);
        Log_keys4(logger,
                  "Generated a shared secret:\n"
                  "     myPublicKey=%s\n"
                  "    herPublicKey=%s\n"
                  "    passwordHash=%s\n"
                  "    outputSecret=%s\n",
                  myPublicKeyHex, herPublicKeyHex, passwordHashHex, outputSecretHex);
    #endif
}
Пример #9
0
int main(void)
{
  int i;
  crypto_stream_aes256estream(output,4194304,nonce,firstkey);
  crypto_hash_sha256(h,output,sizeof output);
  for (i = 0;i < 32;++i) printf("%02x",h[i]); printf("\n");
  return 0;
}
Пример #10
0
int
yacl_sha256 (const uint8_t *in, size_t len, uint8_t out[YACL_SHA256_LEN])
{
#ifdef HAVE_LIBSODIUM
  return crypto_hash_sha256 (out, in, len);
#else
  return sha256 (in, len, out);
#endif
}
Пример #11
0
main(int argc, char **argv)
{

  if (argc<2)
  {
    write(2,USAGE,strlen(USAGE));
    exit(64);
  }

  unsigned char cache[131072*32]={0};

  struct passwd *urcd = getpwnam("urcd");

  if ((!urcd)
  || (chdir(argv[1]))
  || (chroot(argv[1]))
  || (setgroups(0,'\x00'))
  || (setgid(urcd->pw_gid))
  || (setuid(urcd->pw_uid))) exit(64);

  unsigned char buffer[16+8+65536+32];
  unsigned char hash[32];
  int i, n, l;

  while (1)
  {

    readbuffer: if (read(0,buffer,2)<2) exit(1);

    n = 0;
    l = 16 + 8 + buffer[0] * 256 + buffer[1];

    while (n<l)
    {
      i = read(0,buffer+n,l-n);
      if (i<1) exit(2);
      n += i;
    }

    crypto_hash_sha256(hash,buffer,l);

    for (i=131072*32-32;i>-32;i-=32) if (!crypto_verify_32(hash,cache+i))
    {
      if (write(1,"\1",1)<1) exit(3);
      goto readbuffer;
    }

    memcpy(cache,cache+32,131072*32-32);
    memcpy(cache+131072*32-32,hash,32);

    if (write(1,"\0",1)<1) exit(4);

  }

}
Пример #12
0
static inline void hashPassword(uint8_t secretOut[32],
                                union CryptoHeader_Challenge* challengeOut,
                                const String* login,
                                const String* password,
                                const uint8_t authType)
{
    crypto_hash_sha256(secretOut, (uint8_t*) password->bytes, password->len);
    uint8_t tempBuff[32];
    if (authType == 1) {
        crypto_hash_sha256(tempBuff, secretOut, 32);
    } else if (authType == 2) {
        crypto_hash_sha256(tempBuff, (uint8_t*) login->bytes, login->len);
    } else {
        Assert_failure("Unsupported auth type [%u]", authType);
    }
    Bits_memcpyConst(challengeOut->bytes, tempBuff, CryptoHeader_Challenge_SIZE);
    CryptoHeader_setAuthChallengeDerivations(challengeOut, 0);
    challengeOut->challenge.type = authType;
    challengeOut->challenge.additional = 0;
}
Пример #13
0
PyObject *pycrypto_hash_sha256(PyObject *self, PyObject *args, PyObject *kw){
  char *m;
  Py_ssize_t msize=0;
  unsigned char h[crypto_hash_sha256_BYTES];
  static const char *kwlist[] = {"m",0};

  if (!PyArg_ParseTupleAndKeywords(args, kw, "|s#:crypto_hash_sha256", (char **)kwlist, &m, &msize)){
    return (PyObject *)0;}

  crypto_hash_sha256(h, (const unsigned char *)m, msize);

  return PyBytes_FromStringAndSize((char *)h, crypto_hash_sha256_BYTES);}
Пример #14
0
Auth::Response Auth::getResponse(const Challenge &challenge) const
{
    Response response;

    int inputlen = passphrase.length() + challenge.size();
    unsigned char input[inputlen];
    memcpy(input, passphrase.c_str(), passphrase.length());
    memcpy(input + passphrase.length(), &challenge[0], challenge.size());

    crypto_hash_sha256(&response.data[0], input, inputlen);

    return response;
}
Пример #15
0
int main()
{
  struct stat st;
  int ch;

  if (fstat(0,&st) == 0) {
    input = mmap(0,st.st_size,PROT_READ,MAP_SHARED,0,0);
    if (input != MAP_FAILED) {
      crypto_hash_sha256(h,input,st.st_size);
      h_print();
      return 0;
    }
  }

  input = 0;
  inputalloc = 0;
  inputlen = 0;

  while ((ch = getchar()) != EOF) {
    if (inputlen >= inputalloc) {
      void *newinput;
      while (inputlen >= inputalloc)
        inputalloc = inputalloc * 2 + 1;
      if (posix_memalign(&newinput,16,inputalloc) != 0) return 111;
      memcpy(newinput,input,inputlen);
      free(input);
      input = newinput;
    }
    input[inputlen++] = ch;
  }

  crypto_hash_sha256(h,input,inputlen);
  h_print();

  return 0;
}
Пример #16
0
void random_oracle(unsigned char *c_bin,  double v[PARAM_M], const unsigned char *m, unsigned long long mlen)
{
  int32_t t[PARAM_M];
  unsigned long long i;
  unsigned char buf[PARAM_M+mlen];

  compress_v(t, v);
  
  for(i=0; i<PARAM_M; i++)
    buf[i] = t[i];
  for(i=0; i<mlen; i++)
    buf[i+PARAM_M] = m[i];

  crypto_hash_sha256(c_bin, buf, PARAM_M+mlen);
}
Пример #17
0
static inline void getPasswordHash_typeOne(uint8_t output[32],
                                           uint16_t derivations,
                                           struct CryptoAuth_Auth* auth)
{
    Bits_memcpyConst(output, auth->secret, 32);
    if (derivations) {
        union {
            uint8_t bytes[2];
            uint8_t asShort;
        } deriv = { .asShort = derivations };

        output[0] ^= deriv.bytes[0];
        output[1] ^= deriv.bytes[1];

        crypto_hash_sha256(output, output, 32);
    }
}
Пример #18
0
int crypto_sign(
  unsigned char *sm,unsigned long long *smlen,
  const unsigned char *m,unsigned long long mlen,
  const unsigned char *sk
)
{
  unsigned char h[32];
  int i;

  crypto_hash_sha256(h,m,mlen);
  if (signedshortmessage(sm,smlen,h,SHORTMESSAGE_BYTES,sk,SECRETKEY_BYTES) < 0) return -1;
  for (i = 0;i < mlen;++i) {
    sm[*smlen] = m[i];
    ++*smlen;
  }
  return 0;
}
Пример #19
0
/**
 * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen):
 * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and
 * write the output to buf.  The value dkLen must be at most 32 * (2^32 - 1).
 */
void
PBKDF2_SHA256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt,
              size_t saltlen, uint64_t c, uint8_t * buf, size_t dkLen)
{
        uint8_t         key[32] = {0};
        size_t          i;
        uint8_t         salt_and_ivec[saltlen + 4];
        uint8_t         U[32];
        uint8_t         T[32];
        uint64_t        j;
        int             k;
        size_t          clen;

    if (passwdlen > 32) {
        /* For some reason libsodium allows 64byte keys meaning keys 
         * between 32byte and 64bytes are not compatible with libsodium. 
           toxencryptsave should only give 32byte passwds so this isn't an issue here.*/
        crypto_hash_sha256(key, passwd, passwdlen);
    } else {
        memcpy(key, passwd, passwdlen);
    }

    memcpy(salt_and_ivec, salt, saltlen);

        for (i = 0; i * 32 < dkLen; i++) {
                be32enc(salt_and_ivec + saltlen, (uint32_t)(i + 1));
                crypto_auth_hmacsha256(U, salt_and_ivec, sizeof(salt_and_ivec), key);

                memcpy(T, U, 32);

                for (j = 2; j <= c; j++) {
                        crypto_auth_hmacsha256(U, U, 32, key);

                        for (k = 0; k < 32; k++) {
                                T[k] ^= U[k];
            }
                }

                clen = dkLen - i * 32;
                if (clen > 32) {
                        clen = 32;
        }
                memcpy(&buf[i * 32], T, clen);
        }
    sodium_memzero((void *) key, sizeof(key));
}
Пример #20
0
QString ClientConfiguration::toBackup(QString const& password) const {
	QByteArray encryptionKey(BACKUP_ENCRYPTION_KEY_BYTES, 0x00);

	// Generate a Salt
	QByteArray salt(BACKUP_SALT_BYTES, 0x00);
	randombytes_buf(salt.data(), BACKUP_SALT_BYTES);

	// Convert the password into bytes
	QByteArray password8Bit = password.toUtf8();

	// Generate the encryption key for the Backup from the Salt and the Password
	PKCS5_PBKDF2_HMAC(reinterpret_cast<unsigned char*>(password8Bit.data()), password8Bit.size(), reinterpret_cast<unsigned char*>(salt.data()), BACKUP_SALT_BYTES, BACKUP_KEY_PBKDF_ITERATIONS, BACKUP_ENCRYPTION_KEY_BYTES, reinterpret_cast<unsigned char*>(encryptionKey.data()));

	QByteArray nonceBytes(crypto_stream_NONCEBYTES, 0x00);

	// The backup content
	QByteArray clientId(IdentityHelper::uint64ToIdentityString(getClientIdentity().getContactId()).toLatin1());
	if (clientId.size() != BACKUP_IDENTITY_BYTES) {
		throw InternalErrorException() << QString("Could not build backup - invalid client identity length (%1 vs. %2 Bytes).").arg(clientId.size()).arg(BACKUP_IDENTITY_BYTES).toStdString();
	}
	QByteArray clientSecKey(getClientLongTermKeyPair().getPrivateKey());
	if (clientSecKey.size() != PROTO_KEY_LENGTH_BYTES) {
		throw InternalErrorException() << QString("Could not build backup - invalid client secret key length (%1 vs. %2 Bytes).").arg(clientSecKey.size()).arg(PROTO_KEY_LENGTH_BYTES).toStdString();
	}

	QByteArray backup(salt);
	backup.append(clientId);
	backup.append(clientSecKey);

	// Compute Hash
	QByteArray controlHash(crypto_hash_sha256_BYTES, 0x00);
	crypto_hash_sha256(reinterpret_cast<unsigned char*>(controlHash.data()), reinterpret_cast<unsigned char*>(backup.data() + BACKUP_SALT_BYTES), BACKUP_IDENTITY_BYTES + PROTO_KEY_LENGTH_BYTES);
	backup.append(controlHash.left(BACKUP_HASH_BYTES));

	if (backup.size() != (BACKUP_SALT_BYTES + BACKUP_IDENTITY_BYTES + PROTO_KEY_LENGTH_BYTES + BACKUP_HASH_BYTES)) {
		throw InternalErrorException() << QString("Could not build backup - invalid packet length (%1 vs. %2 Bytes).").arg(clientSecKey.size()).arg(BACKUP_SALT_BYTES + BACKUP_IDENTITY_BYTES + PROTO_KEY_LENGTH_BYTES + BACKUP_HASH_BYTES).toStdString();
	}

	// The Backup is build from SALT + IDENTITY + KEY + HASH
	crypto_stream_xor(reinterpret_cast<unsigned char*>(backup.data() + BACKUP_SALT_BYTES), reinterpret_cast<unsigned char*>(backup.data() + BACKUP_SALT_BYTES), BACKUP_IDENTITY_BYTES + PROTO_KEY_LENGTH_BYTES + BACKUP_HASH_BYTES, reinterpret_cast<unsigned char*>(nonceBytes.data()), reinterpret_cast<unsigned char*>(encryptionKey.data()));

	// Encode in Base32
	return Base32::encodeBase32Sequence(backup);
}
Пример #21
0
Файл: key.c Проект: aloisdg/pcp
/*
 * AS of 16/01/2014 I'm using scrypt() instead of my crafted key
 * derivation function. However, I create a hash from the pcp_scrypt()
 * result anyway because I need a curve25519 secret.
 */
byte *pcp_derivekey(PCPCTX *ptx, char *passphrase, byte *nonce) {
  byte *key = smalloc(crypto_secretbox_KEYBYTES);
  size_t plen = strnlen(passphrase, 255);

  /*  create the scrypt hash */
  byte *scrypted = pcp_scrypt(ptx, passphrase, plen, nonce, LNONCE);

  /*  make a hash from the scrypt() result */
  crypto_hash_sha256(key, (byte*)scrypted, 64);

  /*  turn the 32byte hash into a secret key */
  key[0]  &= 248;
  key[31] &= 127;
  key[31] |= 64;

  /* done */
  sfree(scrypted);
  return key;
}
Пример #22
0
int main(void)
{
    int i;

    crypto_stream(output, 4194304, nonce, firstkey);
    crypto_hash_sha256(h, output, sizeof output);

    for (i = 0; i < 32; ++i)
        printf("%02x", h[i]);
    printf("\n");

    assert(crypto_stream_keybytes() > 0U);
    assert(crypto_stream_noncebytes() > 0U);
    assert(strcmp(crypto_stream_primitive(), "xsalsa20") == 0);
    assert(crypto_stream_keybytes() == crypto_stream_xsalsa20_keybytes());
    assert(crypto_stream_noncebytes() == crypto_stream_xsalsa20_noncebytes());

    return 0;
}
Пример #23
0
ClientConfiguration::BackupData ClientConfiguration::fromBackup(QString const& backup, QString const& password) {
	QByteArray decodedBase32 = Base32::decodeBase32Sequence(backup);
	if (decodedBase32.size() != BACKUP_DECODED_BYTES) {
		throw IllegalArgumentException() << "Invalid Backup: Size of decoded Backup String is incorrect (" << decodedBase32.size() << " Bytes instead of " << BACKUP_DECODED_BYTES << " Bytes).";
	}

	unsigned char encryptionKey[BACKUP_ENCRYPTION_KEY_BYTES];
	sodium_memzero(encryptionKey, BACKUP_ENCRYPTION_KEY_BYTES);

	// The pointer to the base32-decoded Backup
	unsigned char* decodedBase32Ptr = reinterpret_cast<unsigned char*>(decodedBase32.data());

	// The Salt used in the PBKDF2 Key Derivation process is embedded in the first 8 bytes of the Backup.
	QByteArray password8Bit = password.toUtf8();
	PKCS5_PBKDF2_HMAC(reinterpret_cast<unsigned char*>(password8Bit.data()), password8Bit.size(), decodedBase32Ptr, BACKUP_SALT_BYTES, BACKUP_KEY_PBKDF_ITERATIONS, BACKUP_ENCRYPTION_KEY_BYTES, encryptionKey);

	unsigned char nonceBytes[crypto_stream_NONCEBYTES];
	sodium_memzero(nonceBytes, crypto_stream_NONCEBYTES);

	crypto_stream_xor(&decodedBase32Ptr[BACKUP_SALT_BYTES], &decodedBase32Ptr[BACKUP_SALT_BYTES], BACKUP_IDENTITY_BYTES + PROTO_KEY_LENGTH_BYTES + BACKUP_HASH_BYTES, nonceBytes, encryptionKey);

	// The last two bytes of the Backup contain the truncated SHA-256 Hash over the identity and its Private Key.
	unsigned char controlHash[crypto_hash_sha256_BYTES];
	sodium_memzero(controlHash, crypto_hash_sha256_BYTES);
	crypto_hash_sha256(controlHash, &(decodedBase32Ptr[BACKUP_SALT_BYTES]), BACKUP_IDENTITY_BYTES + PROTO_KEY_LENGTH_BYTES);

	if (sodium_memcmp(&(decodedBase32Ptr[BACKUP_SALT_BYTES + BACKUP_IDENTITY_BYTES + PROTO_KEY_LENGTH_BYTES]), controlHash, BACKUP_HASH_BYTES) != 0) {
		throw IllegalArgumentException() << "Decryption of Backup failed: Invalid Control Hash (" << controlHash[0] << controlHash[1] << " vs. " << decodedBase32Ptr[BACKUP_SALT_BYTES + BACKUP_IDENTITY_BYTES + PROTO_KEY_LENGTH_BYTES] << decodedBase32Ptr[BACKUP_SALT_BYTES + BACKUP_IDENTITY_BYTES + PROTO_KEY_LENGTH_BYTES + 1] << ").";
	}

	unsigned char derivedPublicKey[PROTO_KEY_LENGTH_BYTES];
	crypto_scalarmult_base(derivedPublicKey, &decodedBase32Ptr[BACKUP_SALT_BYTES + BACKUP_IDENTITY_BYTES]);
	KeyPair kp = KeyPair::fromArrays(derivedPublicKey, &decodedBase32Ptr[BACKUP_SALT_BYTES + BACKUP_IDENTITY_BYTES]);

	QString identityString(QByteArray(reinterpret_cast<char*>(&decodedBase32Ptr[BACKUP_SALT_BYTES]), BACKUP_IDENTITY_BYTES));
	if (!isValidIdentity(identityString)) {
		throw IllegalArgumentException() << "Invalid ClientConfiguration: Decryption of Backup failed: Not a valid Identity.";
	}

	return BackupData(ContactId(identityString.toUtf8()), kp);
}
Пример #24
0
/**
 * Get a shared secret.
 *
 * @param outputSecret an array to place the shared secret in.
 * @param myPrivateKey
 * @param herPublicKey
 * @param logger
 * @param passwordHash a 32 byte value known to both ends, this must be provably pseudorandom
 *                     the first 32 bytes of a sha256 output from hashing a password is ok,
 *                     whatever she happens to send me in the Auth field is NOT ok.
 *                     If this field is null, the secret will be generated without the password.
 */
static inline void getSharedSecret(uint8_t outputSecret[32],
                                   uint8_t myPrivateKey[32],
                                   uint8_t herPublicKey[32],
                                   uint8_t passwordHash[32],
                                   struct Log* logger)
{
    if (passwordHash == NULL) {
        crypto_box_curve25519xsalsa20poly1305_beforenm(outputSecret, herPublicKey, myPrivateKey);
    } else {
        union {
            struct {
                uint8_t key[32];
                uint8_t passwd[32];
            } components;
            uint8_t bytes[64];
        } buff;

        crypto_scalarmult_curve25519(buff.components.key, myPrivateKey, herPublicKey);
        Bits_memcpyConst(buff.components.passwd, passwordHash, 32);
        crypto_hash_sha256(outputSecret, buff.bytes, 64);
    }
    #ifdef Log_KEYS
        uint8_t myPublicKeyHex[65];
        printHexPubKey(myPublicKeyHex, myPrivateKey);
        uint8_t herPublicKeyHex[65];
        printHexKey(herPublicKeyHex, herPublicKey);
        uint8_t passwordHashHex[65];
        printHexKey(passwordHashHex, passwordHash);
        uint8_t outputSecretHex[65] = "NULL";
        printHexKey(outputSecretHex, outputSecret);
        Log_keys(logger,
                  "Generated a shared secret:\n"
                  "     myPublicKey=%s\n"
                  "    herPublicKey=%s\n"
                  "    passwordHash=%s\n"
                  "    outputSecret=%s\n",
                  myPublicKeyHex, herPublicKeyHex, passwordHashHex, outputSecretHex);
    #endif
}
Пример #25
0
int crypto_sign_open(
  unsigned char *m,unsigned long long *mlen,
  const unsigned char *sm,unsigned long long smlen,
  const unsigned char *pk
)
{
  unsigned char h[32];
  unsigned long long hlen;
  int i;
  unsigned char hcheck[32];
  unsigned char hchecksum;

  if (smlen < SIGNATURE_BYTES) return -100;
  i = shortmessagesigned(h,&hlen,sm,SIGNATURE_BYTES,pk,PUBLICKEY_BYTES);
  if (i < 0) return i;

  for (i = SIGNATURE_BYTES;i < smlen;++i) m[i - SIGNATURE_BYTES] = sm[i];
  *mlen = smlen - SIGNATURE_BYTES;
  crypto_hash_sha256(hcheck,m,*mlen);
  hchecksum = 0;
  for (i = 0;i < SHORTMESSAGE_BYTES;++i) hchecksum |= (hcheck[i] ^ h[i]);
  if (hchecksum) return -100;
  return 0;
}
Пример #26
0
void crypto_sha256(uint8_t *hash, const uint8_t *data, size_t length)
{
    crypto_hash_sha256(hash, data, length);
}
Пример #27
0
/**
 * send a message
 */
static void adminChannelSendData(struct Admin* admin,
                                 uint32_t channelNum,
                                 const void *data,
                                 uint32_t length)
{
    /* if this changes, we need to fragment the messages
    * into MAX_MESSAGE_SIZE chunks
    */
    Assert_compileTime(MAX_API_REQUEST_SIZE == MAX_MESSAGE_SIZE);

    Assert_true(length <= MAX_MESSAGE_SIZE);

    struct Admin_MessageHeader header = {
        .magic = admin->pipeMagic,
        .length = length,
        .channelNum = channelNum
    };
    const uint8_t* buf = (const uint8_t*) data;

    // TODO: check result, buffer writes
    write(admin->outFd, &header, Admin_MessageHeader_SIZE);
    if (length > 0) {
        write(admin->outFd, buf, length);
    }
}

/**
 * public function to send responses
 */
void Admin_sendMessage(Dict* message, String* txid, struct Admin* admin)
{
    if (!admin) {
        return;
    }
    Assert_true(txid);

    uint32_t channelNum;
    struct Admin_Channel* channel = adminChannelFindByTxid(admin, txid, &channelNum);

    if (!channel) {
        // txid too short, invalid channel number, closed channel or not matching serial
        Log_debug(admin->logger,
                  "Dropped response because channel isn't open anymore.");
        return;
    }

    uint8_t buff[MAX_API_REQUEST_SIZE];

    uint8_t allocBuff[256];
    struct Allocator* allocator = BufferAllocator_new(allocBuff, 256);

    // Bounce back the user-supplied txid.
    String userTxid = {
        .bytes = txid->bytes + Admin_TxidPrefix_SIZE,
        .len = txid->len - Admin_TxidPrefix_SIZE
    };
    if (txid->len > Admin_TxidPrefix_SIZE) {
        Dict_putString(message, TXID, &userTxid, allocator);
    }

    struct Writer* w = ArrayWriter_new(buff, sizeof(buff), allocator);
    StandardBencSerializer_get()->serializeDictionary(w, message);

    adminChannelSendData(admin, channelNum, buff, w->bytesWritten(w));
}

/**
 * close a channel (for example if an error happened or we received non-empty
 * messages on a invalid channel number)
 * also used to cleanup if we receive a close message
 */
static void adminChannelClose(struct Admin* admin, uint32_t channelNum)
{
    struct Admin_Channel* channel = adminChannelFindById(admin, channelNum);

    if (channel) {
        switch (channel->state) {
        case Admin_ChannelState_OPEN:
            break;
        case Admin_ChannelState_CLOSED:
        case Admin_ChannelState_WAIT_FOR_CLOSE:
            return; // already sent close, nothing to do
        }
        channel->state = Admin_ChannelState_WAIT_FOR_CLOSE;

        // clean up bufers
        channel->bufferLen = 0;
        channel->buffer = NULL;
        if (channel->allocator) {
            channel->allocator->free(channel->allocator);
            channel->allocator = NULL;
        }
    }
    adminChannelSendData(admin, channelNum, NULL, 0);
}

/**
 * handle a received channel close (the received header is in admin->messageHeader)
 * as invalid channels are never OPEN we never have to ACK a close on them
 */
static void adminChannelHandleClose(struct Admin* admin)
{
    uint32_t channelNum = admin->messageHeader.channelNum;
    struct Admin_Channel* channel = adminChannelFindById(admin, channelNum);

    if (channel) {
        switch (channel->state) {
        case Admin_ChannelState_OPEN:
            // close active channel
            adminChannelClose(admin, channelNum);
            // now the state is WAIT_FOR_CLOSE, set it to CLOSED
            channel->state = Admin_ChannelState_CLOSED;
            break;
        case Admin_ChannelState_WAIT_FOR_CLOSE:
            channel->state = Admin_ChannelState_CLOSED;
            channel->serial++;
            break;
        case Admin_ChannelState_CLOSED:
            // nothing to do
            break;
        }
    }
}

static inline bool authValid(Dict* message, uint8_t* buffer, uint32_t length, struct Admin* admin)
{
    String* cookieStr = Dict_getString(message, String_CONST("cookie"));
    uint32_t cookie = (cookieStr != NULL) ? strtoll(cookieStr->bytes, NULL, 10) : 0;
    if (!cookie) {
        int64_t* cookieInt = Dict_getInt(message, String_CONST("cookie"));
        cookie = (cookieInt) ? *cookieInt : 0;
    }
    uint64_t nowSecs = Time_currentTimeSeconds(admin->eventBase);
    String* submittedHash = Dict_getString(message, String_CONST("hash"));
    if (cookie >  nowSecs || cookie < nowSecs - 20 || !submittedHash || submittedHash->len != 64) {
        return false;
    }

    uint8_t* hashPtr = (uint8_t*) strstr((char*) buffer, submittedHash->bytes);

    if (!hashPtr || !admin->password) {
        return false;
    }

    uint8_t passAndCookie[64];
    snprintf((char*) passAndCookie, 64, "%s%u", admin->password->bytes, cookie);
    uint8_t hash[32];
    crypto_hash_sha256(hash, passAndCookie, strlen((char*) passAndCookie));
    Hex_encode(hashPtr, 64, hash, 32);

    crypto_hash_sha256(hash, buffer, length);
    Hex_encode(hashPtr, 64, hash, 32);
    return memcmp(hashPtr, submittedHash->bytes, 64) == 0;
}
Пример #28
0
const char *checksum_compute(void)
{
    long long i;
    long long j;

    for (i = 0; i < CHECKSUM_BYTES; ++i) {
        long long mlen = i;
        long long klen = crypto_auth_KEYBYTES;
        long long hlen = crypto_auth_BYTES;

        for (j = -16; j < 0; ++j) h[j] = rand();
        for (j = -16; j < 0; ++j) k[j] = rand();
        for (j = -16; j < 0; ++j) m[j] = rand();
        for (j = hlen; j < hlen + 16; ++j) h[j] = rand();
        for (j = klen; j < klen + 16; ++j) k[j] = rand();
        for (j = mlen; j < mlen + 16; ++j) m[j] = rand();
        for (j = -16; j < hlen + 16; ++j) h2[j] = h[j];
        for (j = -16; j < klen + 16; ++j) k2[j] = k[j];
        for (j = -16; j < mlen + 16; ++j) m2[j] = m[j];

        if (crypto_auth(h,m,mlen,k) != 0) return "crypto_auth returns nonzero";

        for (j = -16; j < klen + 16; ++j) if (k[j] != k2[j]) return "crypto_auth overwrites k";
        for (j = -16; j < mlen + 16; ++j) if (m[j] != m2[j]) return "crypto_auth overwrites m";
        for (j = -16; j < 0; ++j) if (h[j] != h2[j]) return "crypto_auth writes before output";
        for (j = hlen; j < hlen + 16; ++j) if (h[j] != h2[j]) return "crypto_auth writes after output";

        for (j = -16; j < 0; ++j) h[j] = rand();
        for (j = -16; j < 0; ++j) k[j] = rand();
        for (j = -16; j < 0; ++j) m[j] = rand();
        for (j = hlen; j < hlen + 16; ++j) h[j] = rand();
        for (j = klen; j < klen + 16; ++j) k[j] = rand();
        for (j = mlen; j < mlen + 16; ++j) m[j] = rand();
        for (j = -16; j < hlen + 16; ++j) h2[j] = h[j];
        for (j = -16; j < klen + 16; ++j) k2[j] = k[j];
        for (j = -16; j < mlen + 16; ++j) m2[j] = m[j];

        if (crypto_auth(m2,m2,mlen,k) != 0) return "crypto_auth returns nonzero";
        for (j = 0; j < hlen; ++j) if (m2[j] != h[j]) return "crypto_auth does not handle m overlap";
        for (j = 0; j < hlen; ++j) m2[j] = m[j];
        if (crypto_auth(k2,m2,mlen,k2) != 0) return "crypto_auth returns nonzero";
        for (j = 0; j < hlen; ++j) if (k2[j] != h[j]) return "crypto_auth does not handle k overlap";
        for (j = 0; j < hlen; ++j) k2[j] = k[j];

        if (crypto_auth_verify(h,m,mlen,k) != 0) return "crypto_auth_verify returns nonzero";

        for (j = -16; j < hlen + 16; ++j) if (h[j] != h2[j]) return "crypto_auth overwrites h";
        for (j = -16; j < klen + 16; ++j) if (k[j] != k2[j]) return "crypto_auth overwrites k";
        for (j = -16; j < mlen + 16; ++j) if (m[j] != m2[j]) return "crypto_auth overwrites m";

        crypto_hash_sha256(h2,h,hlen);
        for (j = 0; j < klen; ++j) k[j] ^= h2[j % 32];
        if (crypto_auth(h,m,mlen,k) != 0) return "crypto_auth returns nonzero";
        if (crypto_auth_verify(h,m,mlen,k) != 0) return "crypto_auth_verify returns nonzero";

        crypto_hash_sha256(h2,h,hlen);
        for (j = 0; j < mlen; ++j) m[j] ^= h2[j % 32];
        m[mlen] = h2[0];
    }
    if (crypto_auth(h,m,CHECKSUM_BYTES,k) != 0) return "crypto_auth returns nonzero";
    if (crypto_auth_verify(h,m,CHECKSUM_BYTES,k) != 0) return "crypto_auth_verify returns nonzero";

    sodium_bin2hex(checksum, sizeof checksum, h, crypto_auth_BYTES);

    return 0;
}
Пример #29
0
Файл: key.c Проект: aloisdg/pcp
byte *pcpkey_getchecksum(pcp_key_t *k) {
  byte *hash = ucmalloc(32);
  crypto_hash_sha256(hash, k->pub, LBOXPUB);
  return hash;
}
Пример #30
0
SODIUM_EXPORT int
crypto_hash_sha256_ref(unsigned char *out, const unsigned char *in,
                       unsigned long long inlen)
{
    return crypto_hash_sha256(out, in, inlen);
}