Beispiel #1
0
void CKeyInfo::SetPassword(const Byte *data, UInt32 size)
{
  NSha1::CContext sha;
  sha.Init();
  sha.Update(data, size);
  DeriveKey(sha, MasterKey);
}
static unsigned char* GeneratePasswordHashUsingSHA1(char *password)
{
	unsigned char hashBuf[20], *inputBuf, *key, *final;
	/* H(0) = H(salt, password)
	 * hashBuf = SHA1Hash(salt, password);
	 * create input buffer for SHA1 from salt and unicode version of password */
	unsigned char passwordBuf[512] = {0};
	int passwordBufSize;
	int i;
	SHA_CTX ctx;

	/* convert key to UTF-16LE */
	passwordBufSize = enc_to_utf16((UTF16*)passwordBuf, 125, (UTF8*)password, strlen(password));
	if (passwordBufSize < 0)
		passwordBufSize = strlen16((UTF16*)passwordBuf);
	passwordBufSize <<= 1;

	inputBuf = (unsigned char *)malloc(salt_struct->saltSize + passwordBufSize);
	memcpy(inputBuf, salt_struct->osalt, salt_struct->saltSize);
	memcpy(inputBuf + salt_struct->saltSize, passwordBuf, passwordBufSize);
	SHA1_Init(&ctx);
	SHA1_Update(&ctx, inputBuf, salt_struct->saltSize + passwordBufSize);
	SHA1_Final(hashBuf, &ctx);
	free(inputBuf);

	/* Generate each hash in turn
	 * H(n) = H(i, H(n-1))
	 * hashBuf = SHA1Hash(i, hashBuf); */
	// Create an input buffer for the hash.  This will be 4 bytes larger than
	// the hash to accommodate the unsigned int iterator value.
	inputBuf = (unsigned char *)malloc(0x14 + 0x04);
	// Create a byte array of the integer and put at the front of the input buffer
	// 1.3.6 says that little-endian byte ordering is expected
	memcpy(inputBuf + 4, hashBuf, 20);
	for (i = 0; i < 50000; i++) {
		*(int *)inputBuf = i; // XXX: size & endianness
		// 'append' the previously generated hash to the input buffer
		SHA1_Init(&ctx);
		SHA1_Update(&ctx, inputBuf, 0x14 + 0x04);
		SHA1_Final(inputBuf + 4, &ctx);
	}
	// Finally, append "block" (0) to H(n)
	// hashBuf = SHA1Hash(hashBuf, 0);
	i = 0;
	memmove(inputBuf, inputBuf + 4, 20);
	memcpy(inputBuf + 20, &i, 4); // XXX: size & endianness
	SHA1_Init(&ctx);
	SHA1_Update(&ctx, inputBuf, 0x14 + 0x04);
	SHA1_Final(hashBuf, &ctx);
	free(inputBuf);

	key = DeriveKey(hashBuf);

	// Should handle the case of longer key lengths as shown in 2.3.4.9
	// Grab the key length bytes of the final hash as the encrypytion key
	final = (unsigned char *)malloc(salt_struct->keySize/8);
Beispiel #3
0
// Called by sqlite and sqlite3_key_interop to attach a key to a database.
int sqlite3CodecAttach(sqlite3 *db, int nDb, const void *pKey, int nKeyLen)
{
  int rc = SQLITE_ERROR;
  HCRYPTKEY hKey = 0;

  // No key specified, could mean either use the main db's encryption or no encryption
  if (!pKey || !nKeyLen)
  {
    if (!nDb)
    {
      return SQLITE_OK; // Main database, no key specified so not encrypted
    }
    else // Attached database, use the main database's key
    {
      // Get the encryption block for the main database and attempt to duplicate the key
      // for use by the attached database
      Pager *p = sqlite3BtreePager(db->aDb[0].pBt);
      LPCRYPTBLOCK pBlock = (LPCRYPTBLOCK)sqlite3pager_get_codecarg(p);

      if (!pBlock) return SQLITE_OK; // Main database is not encrypted so neither will be any attached database
      if (!pBlock->hReadKey) return SQLITE_OK; // Not encrypted

      if (!CryptDuplicateKey(pBlock->hReadKey, NULL, 0, &hKey))
        return rc; // Unable to duplicate the key
    }
  }
  else // User-supplied passphrase, so create a cryptographic key out of it
  {
    hKey = DeriveKey(pKey, nKeyLen);
    if (hKey == MAXDWORD)
    {
      sqlite3Error(db, rc, SQLITECRYPTERROR_PROVIDER);
      return rc;
    }
  }

  // Create a new encryption block and assign the codec to the new attached database
  if (hKey)
  {
    Pager *p = sqlite3BtreePager(db->aDb[nDb].pBt);
    LPCRYPTBLOCK pBlock = CreateCryptBlock(hKey, p, -1, NULL);
    if (!pBlock) return SQLITE_NOMEM;

    sqlite3PagerSetCodec(p, sqlite3Codec, sqlite3CodecSizeChange, sqlite3CodecFree, pBlock);
    //db->aDb[nDb].pAux = pBlock;
    //db->aDb[nDb].xFreeAux = DestroyCryptBlock;

    rc = SQLITE_OK;
  }
  return rc;
}
bool CHDKeyStore::GetKey(const CKeyID &address, CKey &keyOut) const
{
    LOCK(cs_KeyStore);

    std::map<CKeyID, CHDPubKey>::const_iterator mi = mapHDPubKeys.find(address);
    if (mi != mapHDPubKeys.end())
    {
        if (!DeriveKey(mi->second, keyOut))
            return false;

        return true;
    }

    return CCryptoKeyStore::GetKey(address, keyOut);
}
Beispiel #5
0
	void Pkcs5Kdf::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt) const
	{
		DeriveKey (key, password, salt, GetIterationCount());
	}
Beispiel #6
0
HRESULT CDecoder::Init_and_CheckPassword(bool &passwOK)
{
  passwOK = false;
  if (_remSize < 16)
    return E_NOTIMPL;
  Byte *p = _bufAligned;
  UInt16 format = GetUi16(p);
  if (format != 3)
    return E_NOTIMPL;
  UInt16 algId = GetUi16(p + 2);
  if (algId < kAES128)
    return E_NOTIMPL;
  algId -= kAES128;
  if (algId > 2)
    return E_NOTIMPL;
  UInt16 bitLen = GetUi16(p + 4);
  UInt16 flags = GetUi16(p + 6);
  if (algId * 64 + 128 != bitLen)
    return E_NOTIMPL;
  _key.KeySize = 16 + algId * 8;
  bool cert = ((flags & 2) != 0);

  if ((flags & 0x4000) != 0)
  {
    // Use 3DES for rd data
    return E_NOTIMPL;
  }

  if (cert)
  {
    return E_NOTIMPL;
  }
  else
  {
    if ((flags & 1) == 0)
      return E_NOTIMPL;
  }

  UInt32 rdSize = GetUi16(p + 8);

  if (rdSize + 16 > _remSize)
    return E_NOTIMPL;

  const unsigned kPadSize = kAesPadAllign; // is equal to blockSize of cipher for rd

  /*
  if (cert)
  {
    if ((rdSize & 0x7) != 0)
      return E_NOTIMPL;
  }
  else
  */
  {
    // PKCS7 padding
    if (rdSize < kPadSize)
      return E_NOTIMPL;
    if ((rdSize & (kPadSize - 1)) != 0)
      return E_NOTIMPL;
  }

  memmove(p, p + 10, rdSize);
  const Byte *p2 = p + rdSize + 10;
  UInt32 reserved = GetUi32(p2);
  p2 += 4;
  
  /*
  if (cert)
  {
    UInt32 numRecipients = reserved;

    if (numRecipients == 0)
      return E_NOTIMPL;

    {
      UInt32 hashAlg = GetUi16(p2);
      hashAlg = hashAlg;
      UInt32 hashSize = GetUi16(p2 + 2);
      hashSize = hashSize;
      p2 += 4;

      reserved = reserved;
      // return E_NOTIMPL;

      for (unsigned r = 0; r < numRecipients; r++)
      {
        UInt32 specSize = GetUi16(p2);
        p2 += 2;
        p2 += specSize;
      }
    }
  }
  else
  */
  {
    if (reserved != 0)
      return E_NOTIMPL;
  }

  UInt32 validSize = GetUi16(p2);
  p2 += 2;
  const size_t validOffset = p2 - p;
  if ((validSize & 0xF) != 0 || validOffset + validSize != _remSize)
    return E_NOTIMPL;

  {
    RINOK(SetKey(_key.MasterKey, _key.KeySize));
    RINOK(SetInitVector(_iv, 16));
    RINOK(Init());
    Filter(p, rdSize);

    rdSize -= kPadSize;
    for (unsigned i = 0; i < kPadSize; i++)
      if (p[(size_t)rdSize + i] != kPadSize)
        return S_OK; // passwOK = false;
  }

  Byte fileKey[32];
  NSha1::CContext sha;
  sha.Init();
  sha.Update(_iv, _ivSize);
  sha.Update(p, rdSize);
  DeriveKey(sha, fileKey);
  
  RINOK(SetKey(fileKey, _key.KeySize));
  RINOK(SetInitVector(_iv, 16));
  Init();

  memmove(p, p + validOffset, validSize);
  Filter(p, validSize);

  if (validSize < 4)
    return E_NOTIMPL;
  validSize -= 4;
  if (GetUi32(p + validSize) != CrcCalc(p, validSize))
    return S_OK;
  passwOK = true;
  return S_OK;
}
Beispiel #7
0
// Changes the encryption key for an existing database.
int sqlite3_rekey(sqlite3 *db, const unsigned char *pKey, int nKeySize)
{
  Btree *pbt = db->aDb[0].pBt;
  Pager *p = sqlite3BtreePager(pbt);
  LPCRYPTBLOCK pBlock = (LPCRYPTBLOCK)sqlite3pager_get_codecarg(p);
  HCRYPTKEY hKey = DeriveKey(pKey, nKeySize);
  int rc = SQLITE_ERROR;

  if (hKey == MAXDWORD)
  {
    sqlite3Error(db, rc, SQLITECRYPTERROR_PROVIDER);
    return rc;
  }

  if (!pBlock && !hKey) return SQLITE_OK; // Wasn't encrypted to begin with

  // To rekey a database, we change the writekey for the pager.  The readkey remains
  // the same
  if (!pBlock) // Encrypt an unencrypted database
  {
    pBlock = CreateCryptBlock(hKey, p, -1, NULL);
    if (!pBlock)
      return SQLITE_NOMEM;

    pBlock->hReadKey = 0; // Original database is not encrypted
    sqlite3PagerSetCodec(sqlite3BtreePager(pbt), sqlite3Codec, sqlite3CodecSizeChange, sqlite3CodecFree, pBlock);
    //db->aDb[0].pAux = pBlock;
    //db->aDb[0].xFreeAux = DestroyCryptBlock;
  }
  else // Change the writekey for an already-encrypted database
  {
    pBlock->hWriteKey = hKey;
  }

  // Start a transaction
  rc = sqlite3BtreeBeginTrans(pbt, 1);

  if (!rc)
  {
    // Rewrite all the pages in the database using the new encryption key
    Pgno nPage;
    Pgno nSkip = PAGER_MJ_PGNO(p);
    DbPage *pPage;
    Pgno n;

    rc = sqlite3PagerPagecount(p, &nPage);

    for(n = 1; rc == SQLITE_OK && n <= nPage; n ++)
    {
      if (n == nSkip) continue;
      rc = sqlite3PagerGet(p, n, &pPage);
      if(!rc)
      {
        rc = sqlite3PagerWrite(pPage);
        sqlite3PagerUnref(pPage);
      }
    }
  }

  // If we succeeded, try and commit the transaction
  if (!rc)
  {
    rc = sqlite3BtreeCommit(pbt);
  }

  // If we failed, rollback
  if (rc)
  {
    sqlite3BtreeRollback(pbt);
  }

  // If we succeeded, destroy any previous read key this database used
  // and make the readkey equal to the writekey
  if (!rc)
  {
    if (pBlock->hReadKey)
    {
      CryptDestroyKey(pBlock->hReadKey);
    }
    pBlock->hReadKey = pBlock->hWriteKey;
  }
  // We failed.  Destroy the new writekey (if there was one) and revert it back to
  // the original readkey
  else
  {
    if (pBlock->hWriteKey)
    {
      CryptDestroyKey(pBlock->hWriteKey);
    }
    pBlock->hWriteKey = pBlock->hReadKey;
  }

  // If the readkey and writekey are both empty, there's no need for a codec on this
  // pager anymore.  Destroy the crypt block and remove the codec from the pager.
  if (!pBlock->hReadKey && !pBlock->hWriteKey)
  {
    sqlite3PagerSetCodec(p, NULL, NULL, NULL, NULL);
  }

  return rc;
}
Beispiel #8
0
status_t SSO::MBIKeyOld(BString key, BString nonce, BString &response) {
	const char *kSessionHash = "WS-SecureConversationSESSION KEY HASH";
	const char *kSessionEnc = "WS-SecureConversationSESSION KEY ENCRYPTION";
	const uint32 kSessionHashLen = strlen(kSessionHash);
	const uint32 kSessionEncLen = strlen(kSessionEnc);
	const uint8 kNoncePadding = 8;

	uchar *key1 = NULL;
	uchar *key2 = NULL;
	uchar *key3 = NULL;

	// Obtain the three keys for the 3DES encryption
	int32 key1Len = (int32)Base64Decode(key.String(), key.Length(), &key1);
	int32 key2Len = DeriveKey(key1, key1Len, (uchar *)kSessionHash, kSessionHashLen, &key2);
	DeriveKey(key1, key1Len, (uchar *)kSessionEnc, kSessionEncLen, &key3);

	uchar hash[EVP_MAX_MD_SIZE];
	unsigned int hashLen = 0;
	
	// Key 2 is used as the key to the HMAC-SHA() of the Nonce
	HMAC(EVP_sha1(), key2, key2Len, (uchar *)nonce.String(), nonce.Length(), hash, &hashLen);

	// The nonce is padded out by 8 bytes of 0x08
	int32 padNonceLen = nonce.Length() + kNoncePadding;
	uchar *padNonce = (uchar *)calloc(padNonceLen, sizeof(uchar));
	memset(padNonce, 0x08, padNonceLen);
	memcpy(padNonce, nonce.String(), nonce.Length());
	
	const uint32 kKeyLen = 8;
	uchar cbc_key1[kKeyLen];
	uchar cbc_key2[kKeyLen];
	uchar cbc_key3[kKeyLen];
	
	// The 3DES CBC key is Key3
	memcpy(cbc_key1, key3 + (kKeyLen * 0), sizeof(cbc_key1));
	memcpy(cbc_key2, key3 + (kKeyLen * 1), sizeof(cbc_key2));
	memcpy(cbc_key3, key3 + (kKeyLen * 2), sizeof(cbc_key3));

	des_key_schedule ks1;
	des_key_schedule ks2;
	des_key_schedule ks3;
	
	// Create 3DES CBC keys
	DES_set_key(&cbc_key1, &ks1);
	DES_set_key(&cbc_key2, &ks2);
	DES_set_key(&cbc_key3, &ks3);
	
	// Setup the IV
	uchar iv[8];
	for (int8 i = 0; i < 8; i++) iv[i] = rand() * 255;
	des_cblock iv3;
	memcpy(iv3, iv, sizeof(iv));

	// Create a buffer used by the 3DES process
	uchar *buffer = (uchar *)calloc(1024, sizeof(uchar));

	// 3DES the nonce
	DES_ede3_cbc_encrypt(padNonce, buffer, padNonceLen, &ks1, &ks2, &ks3, &iv3, DES_ENCRYPT);

	// Output the results
	BufferWriter *result = new BufferWriter(B_SWAP_HOST_TO_LENDIAN);
	result->WriteInt32(0x0000001C);			// Size of header (28)
	result->WriteInt32(0x00000001);			// CBC crypt
	result->WriteInt32(0x00006603);			// Triple DES
	result->WriteInt32(0x00008004);			// SHA1
	result->WriteInt32(sizeof(iv));			// Length of IV
	result->WriteInt32(hashLen);			// Length of hash
	result->WriteInt32(72);					// Length of cipher
	result->WriteData(iv, sizeof(iv));		// IV
	result->WriteData(hash, hashLen);		// Hash
	result->WriteData(buffer, 72);			// Enc
	
	char *base64Result = Base64Encode((const char *)result->Buffer(), (int32)result->Offset());
	response = base64Result;

	free(key1);
	free(key2);
	free(key3);
	free(padNonce);
	free(buffer);
	free(base64Result);
	
	return B_OK;
};