aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/rt3090/common/crypt_dh.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/rt3090/common/crypt_dh.c')
-rw-r--r--drivers/staging/rt3090/common/crypt_dh.c234
1 files changed, 234 insertions, 0 deletions
diff --git a/drivers/staging/rt3090/common/crypt_dh.c b/drivers/staging/rt3090/common/crypt_dh.c
new file mode 100644
index 000000000000..0f69f2af9038
--- /dev/null
+++ b/drivers/staging/rt3090/common/crypt_dh.c
@@ -0,0 +1,234 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ crypt_dh.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Eddy 2009/01/19 Create AES-128, AES-192, AES-256, AES-CBC
+*/
+
+#include "crypt_dh.h"
+#include "crypt_biginteger.h"
+
+/*
+========================================================================
+Routine Description:
+ Diffie-Hellman public key generation
+
+Arguments:
+ GValue Array in UINT8
+ GValueLength The length of G in bytes
+ PValue Array in UINT8
+ PValueLength The length of P in bytes
+ PrivateKey Private key
+ PrivateKeyLength The length of Private key in bytes
+
+Return Value:
+ PublicKey Public key
+ PublicKeyLength The length of public key in bytes
+
+Note:
+ Reference to RFC2631
+ PublicKey = G^PrivateKey (mod P)
+========================================================================
+*/
+void DH_PublicKey_Generate (
+ IN UINT8 GValue[],
+ IN UINT GValueLength,
+ IN UINT8 PValue[],
+ IN UINT PValueLength,
+ IN UINT8 PrivateKey[],
+ IN UINT PrivateKeyLength,
+ OUT UINT8 PublicKey[],
+ INOUT UINT *PublicKeyLength)
+{
+ PBIG_INTEGER pBI_G = NULL;
+ PBIG_INTEGER pBI_P = NULL;
+ PBIG_INTEGER pBI_PrivateKey = NULL;
+ PBIG_INTEGER pBI_PublicKey = NULL;
+
+ /*
+ * 1. Check the input parameters
+ * - GValueLength, PValueLength and PrivateLength must be large than zero
+ * - PublicKeyLength must be large or equal than PValueLength
+ * - PValue must be odd
+ *
+ * - PValue must be prime number (no implement)
+ * - GValue must be greater than 0 but less than the PValue (no implement)
+ */
+ if (GValueLength == 0) {
+ DBGPRINT(RT_DEBUG_ERROR, ("DH_PublicKey_Generate: G length is (%d)\n", GValueLength));
+ return;
+ } /* End of if */
+ if (PValueLength == 0) {
+ DBGPRINT(RT_DEBUG_ERROR, ("DH_PublicKey_Generate: P length is (%d)\n", PValueLength));
+ return;
+ } /* End of if */
+ if (PrivateKeyLength == 0) {
+ DBGPRINT(RT_DEBUG_ERROR, ("DH_PublicKey_Generate: private key length is (%d)\n", PrivateKeyLength));
+ return;
+ } /* End of if */
+ if (*PublicKeyLength < PValueLength) {
+ DBGPRINT(RT_DEBUG_ERROR, ("DH_PublicKey_Generate: public key length(%d) must be large or equal than P length(%d)\n",
+ *PublicKeyLength, PValueLength));
+ return;
+ } /* End of if */
+ if (!(PValue[PValueLength - 1] & 0x1)) {
+ DBGPRINT(RT_DEBUG_ERROR, ("DH_PublicKey_Generate: P value must be odd\n"));
+ return;
+ } /* End of if */
+
+ /*
+ * 2. Transfer parameters to BigInteger structure
+ */
+ BigInteger_Init(&pBI_G);
+ BigInteger_Init(&pBI_P);
+ BigInteger_Init(&pBI_PrivateKey);
+ BigInteger_Init(&pBI_PublicKey);
+ BigInteger_Bin2BI(GValue, GValueLength, &pBI_G);
+ BigInteger_Bin2BI(PValue, PValueLength, &pBI_P);
+ BigInteger_Bin2BI(PrivateKey, PrivateKeyLength, &pBI_PrivateKey);
+
+ /*
+ * 3. Calculate PublicKey = G^PrivateKey (mod P)
+ * - BigInteger Operation
+ * - Montgomery reduction
+ */
+ BigInteger_Montgomery_ExpMod(pBI_G, pBI_PrivateKey, pBI_P, &pBI_PublicKey);
+
+ /*
+ * 4. Transfer BigInteger structure to char array
+ */
+ BigInteger_BI2Bin(pBI_PublicKey, PublicKey, PublicKeyLength);
+
+ BigInteger_Free(&pBI_G);
+ BigInteger_Free(&pBI_P);
+ BigInteger_Free(&pBI_PrivateKey);
+ BigInteger_Free(&pBI_PublicKey);
+} /* End of DH_PublicKey_Generate */
+
+
+/*
+========================================================================
+Routine Description:
+ Diffie-Hellman secret key generation
+
+Arguments:
+ PublicKey Public key
+ PublicKeyLength The length of Public key in bytes
+ PValue Array in UINT8
+ PValueLength The length of P in bytes
+ PrivateKey Private key
+ PrivateKeyLength The length of Private key in bytes
+
+Return Value:
+ SecretKey Secret key
+ SecretKeyLength The length of secret key in bytes
+
+Note:
+ Reference to RFC2631
+ SecretKey = PublicKey^PrivateKey (mod P)
+========================================================================
+*/
+void DH_SecretKey_Generate (
+ IN UINT8 PublicKey[],
+ IN UINT PublicKeyLength,
+ IN UINT8 PValue[],
+ IN UINT PValueLength,
+ IN UINT8 PrivateKey[],
+ IN UINT PrivateKeyLength,
+ OUT UINT8 SecretKey[],
+ INOUT UINT *SecretKeyLength)
+{
+ PBIG_INTEGER pBI_P = NULL;
+ PBIG_INTEGER pBI_SecretKey = NULL;
+ PBIG_INTEGER pBI_PrivateKey = NULL;
+ PBIG_INTEGER pBI_PublicKey = NULL;
+
+ /*
+ * 1. Check the input parameters
+ * - PublicKeyLength, PValueLength and PrivateLength must be large than zero
+ * - SecretKeyLength must be large or equal than PValueLength
+ * - PValue must be odd
+ *
+ * - PValue must be prime number (no implement)
+ */
+ if (PublicKeyLength == 0) {
+ DBGPRINT(RT_DEBUG_ERROR, ("DH_SecretKey_Generate: public key length is (%d)\n", PublicKeyLength));
+ return;
+ } /* End of if */
+ if (PValueLength == 0) {
+ DBGPRINT(RT_DEBUG_ERROR, ("DH_SecretKey_Generate: P length is (%d)\n", PValueLength));
+ return;
+ } /* End of if */
+ if (PrivateKeyLength == 0) {
+ DBGPRINT(RT_DEBUG_ERROR, ("DH_SecretKey_Generate: private key length is (%d)\n", PrivateKeyLength));
+ return;
+ } /* End of if */
+ if (*SecretKeyLength < PValueLength) {
+ DBGPRINT(RT_DEBUG_ERROR, ("DH_SecretKey_Generate: secret key length(%d) must be large or equal than P length(%d)\n",
+ *SecretKeyLength, PValueLength));
+ return;
+ } /* End of if */
+ if (!(PValue[PValueLength - 1] & 0x1)) {
+ DBGPRINT(RT_DEBUG_ERROR, ("DH_SecretKey_Generate: P value must be odd\n"));
+ return;
+ } /* End of if */
+
+ /*
+ * 2. Transfer parameters to BigInteger structure
+ */
+ BigInteger_Init(&pBI_P);
+ BigInteger_Init(&pBI_PrivateKey);
+ BigInteger_Init(&pBI_PublicKey);
+ BigInteger_Init(&pBI_SecretKey);
+
+ BigInteger_Bin2BI(PublicKey, PublicKeyLength, &pBI_PublicKey);
+ BigInteger_Bin2BI(PValue, PValueLength, &pBI_P);
+ BigInteger_Bin2BI(PrivateKey, PrivateKeyLength, &pBI_PrivateKey);
+
+ /*
+ * 3. Calculate SecretKey = PublicKey^PrivateKey (mod P)
+ * - BigInteger Operation
+ * - Montgomery reduction
+ */
+ BigInteger_Montgomery_ExpMod(pBI_PublicKey, pBI_PrivateKey, pBI_P, &pBI_SecretKey);
+
+ /*
+ * 4. Transfer BigInteger structure to char array
+ */
+ BigInteger_BI2Bin(pBI_SecretKey, SecretKey, SecretKeyLength);
+
+ BigInteger_Free(&pBI_P);
+ BigInteger_Free(&pBI_PrivateKey);
+ BigInteger_Free(&pBI_PublicKey);
+ BigInteger_Free(&pBI_SecretKey);
+} /* End of DH_SecretKey_Generate */