// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/http/des.h"

#include "base/logging.h"

#if defined(USE_OPENSSL)
#include <openssl/des.h>
#include "crypto/openssl_util.h"
#elif defined(USE_NSS)
#include <nss.h>
#include <pk11pub.h>
#include "crypto/nss_util.h"
#elif defined(OS_MACOSX)
#include <CommonCrypto/CommonCryptor.h>
#elif defined(OS_WIN)
#include <windows.h>
#include <wincrypt.h>
#include "crypto/scoped_capi_types.h"
#endif

// The Mac and Windows (CryptoAPI) versions of DESEncrypt are our own code.
// DESSetKeyParity, DESMakeKey, and the Linux (NSS) version of DESEncrypt are
// based on mozilla/security/manager/ssl/src/nsNTLMAuthModule.cpp,
// CVS rev. 1.14.

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Mozilla.
 *
 * The Initial Developer of the Original Code is IBM Corporation.
 * Portions created by IBM Corporation are Copyright (C) 2003
 * IBM Corporation. All Rights Reserved.
 *
 * Contributor(s):
 *   Darin Fisher <darin@meer.net>
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

// Set odd parity bit (in least significant bit position).
static uint8 DESSetKeyParity(uint8 x) {
  if ((((x >> 7) ^ (x >> 6) ^ (x >> 5) ^
        (x >> 4) ^ (x >> 3) ^ (x >> 2) ^
        (x >> 1)) & 0x01) == 0) {
    x |= 0x01;
  } else {
    x &= 0xfe;
  }
  return x;
}

namespace net {

void DESMakeKey(const uint8* raw, uint8* key) {
  key[0] = DESSetKeyParity(raw[0]);
  key[1] = DESSetKeyParity((raw[0] << 7) | (raw[1] >> 1));
  key[2] = DESSetKeyParity((raw[1] << 6) | (raw[2] >> 2));
  key[3] = DESSetKeyParity((raw[2] << 5) | (raw[3] >> 3));
  key[4] = DESSetKeyParity((raw[3] << 4) | (raw[4] >> 4));
  key[5] = DESSetKeyParity((raw[4] << 3) | (raw[5] >> 5));
  key[6] = DESSetKeyParity((raw[5] << 2) | (raw[6] >> 6));
  key[7] = DESSetKeyParity((raw[6] << 1));
}

#if defined(USE_OPENSSL)

void DESEncrypt(const uint8* key, const uint8* src, uint8* hash) {
  crypto::EnsureOpenSSLInit();

  DES_key_schedule ks;
  DES_set_key_unchecked(
      reinterpret_cast<const_DES_cblock*>(const_cast<uint8*>(key)), &ks);

  DES_ecb_encrypt(reinterpret_cast<const_DES_cblock*>(const_cast<uint8*>(src)),
                  reinterpret_cast<DES_cblock*>(hash), &ks, DES_ENCRYPT);
}

#elif defined(USE_NSS)

void DESEncrypt(const uint8* key, const uint8* src, uint8* hash) {
  CK_MECHANISM_TYPE cipher_mech = CKM_DES_ECB;
  PK11SlotInfo* slot = NULL;
  PK11SymKey* symkey = NULL;
  PK11Context* ctxt = NULL;
  SECItem key_item;
  SECItem* param = NULL;
  SECStatus rv;
  unsigned int n;

  crypto::EnsureNSSInit();

  slot = PK11_GetInternalSlot();
  if (!slot)
    goto done;

  key_item.data = const_cast<uint8*>(key);
  key_item.len = 8;
  symkey = PK11_ImportSymKey(slot, cipher_mech,
                             PK11_OriginUnwrap, CKA_ENCRYPT,
                             &key_item, NULL);
  if (!symkey)
    goto done;

  // No initialization vector required.
  param = PK11_ParamFromIV(cipher_mech, NULL);
  if (!param)
    goto done;

  ctxt = PK11_CreateContextBySymKey(cipher_mech, CKA_ENCRYPT,
                                    symkey, param);
  if (!ctxt)
    goto done;

  rv = PK11_CipherOp(ctxt, hash, reinterpret_cast<int*>(&n), 8,
                     const_cast<uint8*>(src), 8);
  if (rv != SECSuccess)
    goto done;

  // TODO(wtc): Should this be PK11_Finalize?
  rv = PK11_DigestFinal(ctxt, hash+8, &n, 0);
  if (rv != SECSuccess)
    goto done;

 done:
  if (ctxt)
    PK11_DestroyContext(ctxt, PR_TRUE);
  if (symkey)
    PK11_FreeSymKey(symkey);
  if (param)
    SECITEM_FreeItem(param, PR_TRUE);
  if (slot)
    PK11_FreeSlot(slot);
}

#elif defined(OS_MACOSX)

void DESEncrypt(const uint8* key, const uint8* src, uint8* hash) {
  CCCryptorStatus status;
  size_t data_out_moved = 0;
  status = CCCrypt(kCCEncrypt, kCCAlgorithmDES, kCCOptionECBMode,
                   key, 8, NULL, src, 8, hash, 8, &data_out_moved);
  DCHECK(status == kCCSuccess);
  DCHECK(data_out_moved == 8);
}

#elif defined(OS_WIN)

void DESEncrypt(const uint8* key, const uint8* src, uint8* hash) {
  crypto::ScopedHCRYPTPROV provider;
  if (!CryptAcquireContext(provider.receive(), NULL, NULL, PROV_RSA_FULL,
                           CRYPT_VERIFYCONTEXT))
    return;

  {
    // Import the DES key.
    struct KeyBlob {
      BLOBHEADER header;
      DWORD key_size;
      BYTE key_data[8];
    };
    KeyBlob key_blob;
    key_blob.header.bType = PLAINTEXTKEYBLOB;
    key_blob.header.bVersion = CUR_BLOB_VERSION;
    key_blob.header.reserved = 0;
    key_blob.header.aiKeyAlg = CALG_DES;
    key_blob.key_size = 8;  // 64 bits
    memcpy(key_blob.key_data, key, 8);

    crypto::ScopedHCRYPTKEY key;
    BOOL import_ok = CryptImportKey(provider,
                                    reinterpret_cast<BYTE*>(&key_blob),
                                    sizeof key_blob, 0, 0, key.receive());
    // Destroy the copy of the key.
    SecureZeroMemory(key_blob.key_data, sizeof key_blob.key_data);
    if (!import_ok)
      return;

    // No initialization vector required.
    DWORD cipher_mode = CRYPT_MODE_ECB;
    if (!CryptSetKeyParam(key, KP_MODE, reinterpret_cast<BYTE*>(&cipher_mode),
                          0))
      return;

    // CryptoAPI requires us to copy the plaintext to the output buffer first.
    CopyMemory(hash, src, 8);
    // Pass a 'Final' of FALSE, otherwise CryptEncrypt appends one additional
    // block of padding to the data.
    DWORD hash_len = 8;
    CryptEncrypt(key, 0, FALSE, 0, hash, &hash_len, 8);
  }
}

#endif

}  // namespace net
