Webserver+3d print
Embed:
(wiki syntax)
Show/hide line numbers
ecdh.c
Go to the documentation of this file.
00001 /** 00002 * @file ecdh.c 00003 * @brief ECDH (Elliptic Curve Diffie-Hellman) key exchange 00004 * 00005 * @section License 00006 * 00007 * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved. 00008 * 00009 * This file is part of CycloneCrypto Open. 00010 * 00011 * This program is free software; you can redistribute it and/or 00012 * modify it under the terms of the GNU General Public License 00013 * as published by the Free Software Foundation; either version 2 00014 * of the License, or (at your option) any later version. 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU General Public License 00022 * along with this program; if not, write to the Free Software Foundation, 00023 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00024 * 00025 * @author Oryx Embedded SARL (www.oryx-embedded.com) 00026 * @version 1.7.6 00027 **/ 00028 00029 //Switch to the appropriate trace level 00030 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL 00031 00032 //Dependencies 00033 #include <stdlib.h> 00034 #include "crypto.h" 00035 #include "ecdh.h" 00036 #include "debug.h" 00037 00038 //Check crypto library configuration 00039 #if (ECDH_SUPPORT == ENABLED) 00040 00041 00042 /** 00043 * @brief Initialize ECDH context 00044 * @param[in] context Pointer to the ECDH context 00045 **/ 00046 00047 void ecdhInit(EcdhContext *context) 00048 { 00049 //Initialize EC domain parameters 00050 ecInitDomainParameters(&context->params); 00051 //Initialize private and public keys 00052 mpiInit(&context->da); 00053 ecInit(&context->qa); 00054 ecInit(&context->qb); 00055 } 00056 00057 00058 /** 00059 * @brief Release ECDH context 00060 * @param[in] context Pointer to the ECDH context 00061 **/ 00062 00063 void ecdhFree(EcdhContext *context) 00064 { 00065 //Release EC domain parameters 00066 ecFreeDomainParameters(&context->params); 00067 //Release private and public keys 00068 mpiFree(&context->da); 00069 ecFree(&context->qa); 00070 ecFree(&context->qb); 00071 } 00072 00073 00074 /** 00075 * @brief ECDH key pair generation 00076 * @param[in] context Pointer to the ECDH context 00077 * @param[in] prngAlgo PRNG algorithm 00078 * @param[in] prngContext Pointer to the PRNG context 00079 * @return Error code 00080 **/ 00081 00082 error_t ecdhGenerateKeyPair(EcdhContext *context, 00083 const PrngAlgo *prngAlgo, void *prngContext) 00084 { 00085 error_t error; 00086 uint_t n; 00087 00088 //Debug message 00089 TRACE_DEBUG("Generating ECDH key pair...\r\n"); 00090 00091 //Let N be the bit length of q 00092 n = mpiGetBitLength(&context->params.q); 00093 00094 //Generated a pseudorandom number 00095 MPI_CHECK(mpiRand(&context->da, n, prngAlgo, prngContext)); 00096 00097 //Make sure that 0 < da < q 00098 if(mpiComp(&context->da, &context->params.q) >= 0) 00099 mpiShiftRight(&context->da, 1); 00100 00101 //Debug message 00102 TRACE_DEBUG(" Private key:\r\n"); 00103 TRACE_DEBUG_MPI(" ", &context->da); 00104 00105 //Compute Qa = da.G 00106 EC_CHECK(ecMult(&context->params, &context->qa, &context->da, &context->params.g)); 00107 EC_CHECK(ecAffinify(&context->params, &context->qa, &context->qa)); 00108 00109 //Debug message 00110 TRACE_DEBUG(" Public key X:\r\n"); 00111 TRACE_DEBUG_MPI(" ", &context->qa.x); 00112 TRACE_DEBUG(" Public key Y:\r\n"); 00113 TRACE_DEBUG_MPI(" ", &context->qa.y); 00114 00115 end: 00116 //Return status code 00117 return error; 00118 } 00119 00120 00121 /** 00122 * @brief Check ECDH public key 00123 * @param[in] params EC domain parameters 00124 * @param[in] publicKey Public key to be checked 00125 * @return Error code 00126 **/ 00127 00128 error_t ecdhCheckPublicKey(const EcDomainParameters *params, EcPoint *publicKey) 00129 { 00130 bool_t valid; 00131 00132 //Verify that 0 <= Qx < p 00133 if(mpiCompInt(&publicKey->x, 0) < 0) 00134 return ERROR_ILLEGAL_PARAMETER; 00135 else if(mpiComp(&publicKey->x, ¶ms->p) >= 0) 00136 return ERROR_ILLEGAL_PARAMETER; 00137 00138 //Verify that 0 <= Qy < p 00139 if(mpiCompInt(&publicKey->y, 0) < 0) 00140 return ERROR_ILLEGAL_PARAMETER; 00141 else if(mpiComp(&publicKey->y, ¶ms->p) >= 0) 00142 return ERROR_ILLEGAL_PARAMETER; 00143 00144 //Check whether the point is on the curve 00145 valid = ecIsPointAffine(params, publicKey); 00146 00147 //Return status code 00148 return valid ? NO_ERROR : ERROR_FAILURE; 00149 } 00150 00151 00152 /** 00153 * @brief Compute ECDH shared secret 00154 * @param[in] context Pointer to the ECDH context 00155 * @param[out] output Buffer where to store the shared secret 00156 * @param[in] outputSize Size of the buffer in bytes 00157 * @param[out] outputLength Length of the resulting shared secret 00158 * @return Error code 00159 **/ 00160 00161 error_t ecdhComputeSharedSecret(EcdhContext *context, 00162 uint8_t *output, size_t outputSize, size_t *outputLength) 00163 { 00164 error_t error; 00165 size_t k; 00166 EcPoint z; 00167 00168 //Debug message 00169 TRACE_DEBUG("Computing Diffie-Hellman shared secret...\r\n"); 00170 00171 //Get the length in octets of the prime modulus 00172 k = mpiGetByteLength(&context->params.p); 00173 00174 //Make sure that the output buffer is large enough 00175 if(outputSize < k) 00176 return ERROR_INVALID_LENGTH; 00177 00178 //Initialize EC points 00179 ecInit(&z); 00180 00181 //Compute Z = da.Qb 00182 EC_CHECK(ecProjectify(&context->params, &context->qb, &context->qb)); 00183 EC_CHECK(ecMult(&context->params, &z, &context->da, &context->qb)); 00184 EC_CHECK(ecAffinify(&context->params, &z, &z)); 00185 00186 //Convert the x-coordinate of Z to an octet string 00187 MPI_CHECK(mpiWriteRaw(&z.x, output, k)); 00188 00189 //Length of the resulting shared secret 00190 *outputLength = k; 00191 00192 //Debug message 00193 TRACE_DEBUG(" Shared secret (%" PRIuSIZE " bytes):\r\n", *outputLength); 00194 TRACE_DEBUG_ARRAY(" ", output, *outputLength); 00195 00196 end: 00197 //Release EC points 00198 ecFree(&z); 00199 00200 //Return status code 00201 return error; 00202 } 00203 00204 #endif 00205
Generated on Tue Jul 12 2022 17:10:13 by
