235 lines
7.9 KiB
C
235 lines
7.9 KiB
C
/*
|
|
*************************************************************************
|
|
* 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 */
|