Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
md2.c
00001 /** 00002 * @file md2.c 00003 * @brief MD2 (Message-Digest Algorithm) 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 * @section Description 00026 * 00027 * The MD2 algorithm takes as input a message of arbitrary length and produces 00028 * as output a 128-bit message digest of the input. Refer to RFC 1319 00029 * 00030 * @author Oryx Embedded SARL (www.oryx-embedded.com) 00031 * @version 1.7.6 00032 **/ 00033 00034 //Switch to the appropriate trace level 00035 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL 00036 00037 //Dependencies 00038 #include <string.h> 00039 #include "crypto.h" 00040 #include "md2.h" 00041 00042 //Check crypto library configuration 00043 #if (MD2_SUPPORT == ENABLED) 00044 00045 //MD2 constants 00046 static const uint8_t s[256] = 00047 { 00048 0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01, 0x3D, 0x36, 0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13, 00049 0x62, 0xA7, 0x05, 0xF3, 0xC0, 0xC7, 0x73, 0x8C, 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C, 0x82, 0xCA, 00050 0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16, 0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12, 00051 0xBE, 0x4E, 0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49, 0xA0, 0xFB, 0xF5, 0x8E, 0xBB, 0x2F, 0xEE, 0x7A, 00052 0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2, 0x07, 0x3F, 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21, 00053 0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27, 0x35, 0x3E, 0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03, 00054 0xFF, 0x19, 0x30, 0xB3, 0x48, 0xA5, 0xB5, 0xD1, 0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56, 0xAA, 0xC6, 00055 0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6, 0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1, 00056 0x45, 0x9D, 0x70, 0x59, 0x64, 0x71, 0x87, 0x20, 0x86, 0x5B, 0xCF, 0x65, 0xE6, 0x2D, 0xA8, 0x02, 00057 0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0, 0xB9, 0xF6, 0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F, 00058 0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A, 0xC3, 0x5C, 0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26, 00059 0x2C, 0x53, 0x0D, 0x6E, 0x85, 0x28, 0x84, 0x09, 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81, 0x4D, 0x52, 00060 0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA, 0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A, 00061 0x78, 0x88, 0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D, 0xE9, 0xCB, 0xD5, 0xFE, 0x3B, 0x00, 0x1D, 0x39, 00062 0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58, 0xD0, 0xE4, 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A, 00063 0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, 0xDB, 0x99, 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14, 00064 }; 00065 00066 //MD2 object identifier (1.2.840.113549.2.2) 00067 static const uint8_t md2Oid[] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x02}; 00068 00069 //Common interface for hash algorithms 00070 const HashAlgo md2HashAlgo = 00071 { 00072 "MD2", 00073 md2Oid, 00074 sizeof(md2Oid), 00075 sizeof(Md2Context), 00076 MD2_BLOCK_SIZE, 00077 MD2_DIGEST_SIZE, 00078 (HashAlgoCompute) md2Compute, 00079 (HashAlgoInit) md2Init, 00080 (HashAlgoUpdate) md2Update, 00081 (HashAlgoFinal) md2Final 00082 }; 00083 00084 00085 /** 00086 * @brief Digest a message using MD2 00087 * @param[in] data Pointer to the message being hashed 00088 * @param[in] length Length of the message 00089 * @param[out] digest Pointer to the calculated digest 00090 * @return Error code 00091 **/ 00092 00093 error_t md2Compute(const void *data, size_t length, uint8_t *digest) 00094 { 00095 //Allocate a memory buffer to hold the MD2 context 00096 Md2Context *context = cryptoAllocMem(sizeof(Md2Context)); 00097 //Failed to allocate memory? 00098 if(context == NULL) 00099 return ERROR_OUT_OF_MEMORY; 00100 00101 //Initialize the MD2 context 00102 md2Init(context); 00103 //Digest the message 00104 md2Update(context, data, length); 00105 //Finalize the MD2 message digest 00106 md2Final(context, digest); 00107 00108 //Free previously allocated memory 00109 cryptoFreeMem(context); 00110 //Successful processing 00111 return NO_ERROR; 00112 } 00113 00114 00115 /** 00116 * @brief Initialize MD2 message digest context 00117 * @param[in] context Pointer to the MD2 context to initialize 00118 **/ 00119 00120 void md2Init(Md2Context *context) 00121 { 00122 //Initialize the 48-byte buffer X 00123 memset(context->x, 0, 48); 00124 //Clear checksum 00125 memset(context->c, 0, 16); 00126 //Number of bytes in the buffer 00127 context->size = 0; 00128 } 00129 00130 00131 /** 00132 * @brief Update the MD2 context with a portion of the message being hashed 00133 * @param[in] context Pointer to the MD2 context 00134 * @param[in] data Pointer to the buffer being hashed 00135 * @param[in] length Length of the buffer 00136 **/ 00137 00138 void md2Update(Md2Context *context, const void *data, size_t length) 00139 { 00140 size_t n; 00141 00142 //Process the incoming data 00143 while(length > 0) 00144 { 00145 //The buffer can hold at most 16 bytes 00146 n = MIN(length, 16 - context->size); 00147 00148 //Copy the data to the buffer 00149 memcpy(context->m + context->size, data, n); 00150 00151 //Update the MD2 context 00152 context->size += n; 00153 //Advance the data pointer 00154 data = (uint8_t *) data + n; 00155 //Remaining bytes to process 00156 length -= n; 00157 00158 //Process message in 16-word blocks 00159 if(context->size == 16) 00160 { 00161 //Transform the 16-word block 00162 md2ProcessBlock(context->m, context->x, context->c); 00163 //Empty the buffer 00164 context->size = 0; 00165 } 00166 } 00167 } 00168 00169 00170 /** 00171 * @brief Finish the MD2 message digest 00172 * @param[in] context Pointer to the MD2 context 00173 * @param[out] digest Calculated digest (optional parameter) 00174 **/ 00175 00176 void md2Final(Md2Context *context, uint8_t *digest) 00177 { 00178 uint_t n; 00179 00180 //Pad the message so that its length is congruent to 0 modulo 16 00181 n = 16 - context->size; 00182 00183 //Append padding bytes 00184 memset(context->m + context->size, n, n); 00185 //Transform the 16-word block 00186 md2ProcessBlock(context->m, context->x, context->c); 00187 00188 //Append the checksum 00189 memcpy(context->m, context->c, 16); 00190 //Transform the 16-word block 00191 md2ProcessBlock(context->m, context->x, context->c); 00192 00193 //Copy the resulting digest 00194 if(digest != NULL) 00195 memcpy(digest, context->digest, MD2_DIGEST_SIZE); 00196 } 00197 00198 00199 /** 00200 * @brief Process message in 16-word blocks 00201 * @param[in] m 16-byte data block to process 00202 * @param[in,out] x 48-byte buffer 00203 * @param[in,out] c 16-byte checksum 00204 **/ 00205 00206 void md2ProcessBlock(const uint8_t *m, uint8_t *x, uint8_t *c) 00207 { 00208 uint_t j; 00209 uint_t k; 00210 uint8_t t; 00211 00212 //Update checksum 00213 for(t = c[15], j = 0; j < 16; j++) 00214 { 00215 c[j] ^= s[m[j] ^ t]; 00216 t = c[j]; 00217 } 00218 00219 //Copy current block into X 00220 for(j = 0; j < 16; j++) 00221 { 00222 x[16 + j] = m[j]; 00223 x[32 + j] = x[16 + j] ^ x[j]; 00224 } 00225 00226 //Encrypt block (18 rounds) 00227 for(t = 0, j = 0; j < 18; j++) 00228 { 00229 //Round j 00230 for(k = 0; k < 48; k++) 00231 { 00232 x[k] ^= s[t]; 00233 t = x[k]; 00234 } 00235 00236 //Set t to (t + j) modulo 256 00237 t = (t + j) & 0xFF; 00238 } 00239 } 00240 00241 #endif 00242
Generated on Tue Jul 12 2022 17:10:14 by
1.7.2