Beispiel #1
0
int
_libssh2_wincng_cipher_crypt(_libssh2_cipher_ctx *ctx,
                             _libssh2_cipher_type(type),
                             int encrypt,
                             unsigned char *block,
                             size_t blocklen)
{
    unsigned char *pbOutput;
    unsigned long cbOutput, cbInput;
    int ret;

    (void)type;

    cbInput = (unsigned long)blocklen;

    if (encrypt) {
        ret = BCryptEncrypt(ctx->hKey, block, cbInput, NULL,
                            ctx->pbIV, ctx->dwIV, NULL, 0, &cbOutput, 0);
    } else {
        ret = BCryptDecrypt(ctx->hKey, block, cbInput, NULL,
                            ctx->pbIV, ctx->dwIV, NULL, 0, &cbOutput, 0);
    }
    if (BCRYPT_SUCCESS(ret)) {
        pbOutput = malloc(cbOutput);
        if (pbOutput) {
            if (encrypt) {
                ret = BCryptEncrypt(ctx->hKey, block, cbInput, NULL,
                                    ctx->pbIV, ctx->dwIV,
                                    pbOutput, cbOutput, &cbOutput, 0);
            } else {
                ret = BCryptDecrypt(ctx->hKey, block, cbInput, NULL,
                                    ctx->pbIV, ctx->dwIV,
                                    pbOutput, cbOutput, &cbOutput, 0);
            }
            if (BCRYPT_SUCCESS(ret)) {
                memcpy(block, pbOutput, cbOutput);
            }

            free(pbOutput);
        } else
            ret = STATUS_NO_MEMORY;
    }

    return BCRYPT_SUCCESS(ret) ? 0 : -1;
}
Beispiel #2
0
bool aes_decrypt_check(m0_kdbx_header_entry_t *hdr, uint8_t *masterkey, m0_kdbx_payload_t *payload)
{
  bool res = false;

  BCRYPT_ALG_HANDLE aes            = NULL;
  BCRYPT_KEY_HANDLE ctx            = NULL;
  NTSTATUS          status         = 0;
  DWORD             len_ciphertext = 0,
                    tmp_len        = 0,
                    key_objectlen  = 0;

  PBYTE             key_object     = NULL;

  uint8_t           plaintext[32]  = {0};
  uint8_t           iv[256]        = {0};
  uint8_t           ivlen          = hdr[ENCRYPTIONIV].len & 0xFF;

  // we need to create a local copy of IV, as it is modified during decryption.
  memcpy(&iv, hdr[ENCRYPTIONIV].data, ivlen);

  // Open an algorithm handle.
  status = BCryptOpenAlgorithmProvider(
                  &aes,
                  BCRYPT_AES_ALGORITHM,
                  NULL,
                  0);

  if(!NT_SUCCESS(status)) {
    printf("[!] Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status);
    goto cleanup;
  }

  // Calculate the size of the buffer to hold the Key Object.
  status = BCryptGetProperty(
                  aes,
                  BCRYPT_OBJECT_LENGTH,
                  (PBYTE)&key_objectlen,
                  sizeof(DWORD),
                  &tmp_len,
                  0);

  if(!NT_SUCCESS(status)) {
    printf("[!] Error 0x%x returned by BCryptGetProperty\n", status);
    goto cleanup;
  }

  // We should use preallocated memory for better performance...
  key_object = (PBYTE)HeapAlloc(GetProcessHeap(), 0, key_objectlen);

  if(NULL == key_object) {
    printf("[!] memory allocation failed\n");
    goto cleanup;
  }

  status = BCryptSetProperty(
                  aes,
                  BCRYPT_CHAINING_MODE,
                  (PBYTE)BCRYPT_CHAIN_MODE_CBC,
                  sizeof(BCRYPT_CHAIN_MODE_CBC),
                  0);

  if(!NT_SUCCESS(status)) {
    printf("[!] Error 0x%x returned by BCryptSetProperty\n", status);
    goto cleanup;
  }

  // Generate the key from supplied input key bytes.
  status = BCryptGenerateSymmetricKey(
                  aes,
                  &ctx,
                  key_object,
                  key_objectlen,
                  masterkey,
                  32,
                  0);

  if(!NT_SUCCESS(status)) {
    printf("[!] Error 0x%x returned by BCryptGenerateSymmetricKey\n", status);
    goto cleanup;
  }

  status = BCryptDecrypt(
                  ctx,
                  payload->encrypted,
                  hdr[STREAMSTARTBYTES].len,
                  NULL,
                  iv,
                  ivlen,
                  plaintext,
                  sizeof(plaintext),
                  &tmp_len,
                  0);

  if(!NT_SUCCESS(status)) {
    printf("[!] Error 0x%x returned by BCryptDecrypt\n", status);
    goto cleanup;
  }

  // success!
  if (0 == memcmp(plaintext, hdr[STREAMSTARTBYTES].data, hdr[STREAMSTARTBYTES].len)) {
    res = true;
    payload->decrypted = malloc(hdr[STREAMSTARTBYTES].len);
    memcpy(payload->decrypted, plaintext, hdr[STREAMSTARTBYTES].len);
  }

cleanup:

  if(aes) {
    BCryptCloseAlgorithmProvider(aes,0);
  }

  if (ctx) {
    BCryptDestroyKey(ctx);
  }

  if(key_object) {
    HeapFree(GetProcessHeap(), 0, key_object);
  }

  return res;
}