Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /**
  2.  * \file mbedtls_md.c
  3.  *
  4.  * \brief Generic message digest wrapper for mbed TLS
  5.  *
  6.  * \author Adriaan de Jong <dejong@fox-it.com>
  7.  *
  8.  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  9.  *  SPDX-License-Identifier: GPL-2.0
  10.  *
  11.  *  This program is free software; you can redistribute it and/or modify
  12.  *  it under the terms of the GNU General Public License as published by
  13.  *  the Free Software Foundation; either version 2 of the License, or
  14.  *  (at your option) any later version.
  15.  *
  16.  *  This program is distributed in the hope that it will be useful,
  17.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  *  GNU General Public License for more details.
  20.  *
  21.  *  You should have received a copy of the GNU General Public License along
  22.  *  with this program; if not, write to the Free Software Foundation, Inc.,
  23.  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  24.  *
  25.  *  This file is part of mbed TLS (https://tls.mbed.org)
  26.  */
  27.  
  28. #if !defined(MBEDTLS_CONFIG_FILE)
  29. #include "mbedtls/config.h"
  30. #else
  31. #include MBEDTLS_CONFIG_FILE
  32. #endif
  33.  
  34. #if defined(MBEDTLS_MD_C)
  35.  
  36. #include "mbedtls/md.h"
  37. #include "mbedtls/md_internal.h"
  38. #include "mbedtls/platform_util.h"
  39.  
  40. #if defined(MBEDTLS_PLATFORM_C)
  41. #include "mbedtls/platform.h"
  42. #else
  43. #include <stdlib.h>
  44. #define mbedtls_calloc    calloc
  45. #define mbedtls_free       free
  46. #endif
  47.  
  48. #include <string.h>
  49.  
  50. #if defined(MBEDTLS_FS_IO)
  51. #include <stdio.h>
  52. #endif
  53.  
  54. /*
  55.  * Reminder: update profiles in x509_crt.c when adding a new hash!
  56.  */
  57. static const int supported_digests[] = {
  58.  
  59. #if defined(MBEDTLS_SHA512_C)
  60.         MBEDTLS_MD_SHA512,
  61.         MBEDTLS_MD_SHA384,
  62. #endif
  63.  
  64. #if defined(MBEDTLS_SHA256_C)
  65.         MBEDTLS_MD_SHA256,
  66.         MBEDTLS_MD_SHA224,
  67. #endif
  68.  
  69. #if defined(MBEDTLS_SHA1_C)
  70.         MBEDTLS_MD_SHA1,
  71. #endif
  72.  
  73. #if defined(MBEDTLS_RIPEMD160_C)
  74.         MBEDTLS_MD_RIPEMD160,
  75. #endif
  76.  
  77. #if defined(MBEDTLS_MD5_C)
  78.         MBEDTLS_MD_MD5,
  79. #endif
  80.  
  81. #if defined(MBEDTLS_MD4_C)
  82.         MBEDTLS_MD_MD4,
  83. #endif
  84.  
  85. #if defined(MBEDTLS_MD2_C)
  86.         MBEDTLS_MD_MD2,
  87. #endif
  88.  
  89.         MBEDTLS_MD_NONE
  90. };
  91.  
  92. const int *mbedtls_md_list( void )
  93. {
  94.     return( supported_digests );
  95. }
  96.  
  97. const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name )
  98. {
  99.     if( NULL == md_name )
  100.         return( NULL );
  101.  
  102.     /* Get the appropriate digest information */
  103. #if defined(MBEDTLS_MD2_C)
  104.     if( !strcmp( "MD2", md_name ) )
  105.         return mbedtls_md_info_from_type( MBEDTLS_MD_MD2 );
  106. #endif
  107. #if defined(MBEDTLS_MD4_C)
  108.     if( !strcmp( "MD4", md_name ) )
  109.         return mbedtls_md_info_from_type( MBEDTLS_MD_MD4 );
  110. #endif
  111. #if defined(MBEDTLS_MD5_C)
  112.     if( !strcmp( "MD5", md_name ) )
  113.         return mbedtls_md_info_from_type( MBEDTLS_MD_MD5 );
  114. #endif
  115. #if defined(MBEDTLS_RIPEMD160_C)
  116.     if( !strcmp( "RIPEMD160", md_name ) )
  117.         return mbedtls_md_info_from_type( MBEDTLS_MD_RIPEMD160 );
  118. #endif
  119. #if defined(MBEDTLS_SHA1_C)
  120.     if( !strcmp( "SHA1", md_name ) || !strcmp( "SHA", md_name ) )
  121.         return mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
  122. #endif
  123. #if defined(MBEDTLS_SHA256_C)
  124.     if( !strcmp( "SHA224", md_name ) )
  125.         return mbedtls_md_info_from_type( MBEDTLS_MD_SHA224 );
  126.     if( !strcmp( "SHA256", md_name ) )
  127.         return mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 );
  128. #endif
  129. #if defined(MBEDTLS_SHA512_C)
  130.     if( !strcmp( "SHA384", md_name ) )
  131.         return mbedtls_md_info_from_type( MBEDTLS_MD_SHA384 );
  132.     if( !strcmp( "SHA512", md_name ) )
  133.         return mbedtls_md_info_from_type( MBEDTLS_MD_SHA512 );
  134. #endif
  135.     return( NULL );
  136. }
  137.  
  138. const mbedtls_md_info_t *mbedtls_md_info_from_type( mbedtls_md_type_t md_type )
  139. {
  140.     switch( md_type )
  141.     {
  142. #if defined(MBEDTLS_MD2_C)
  143.         case MBEDTLS_MD_MD2:
  144.             return( &mbedtls_md2_info );
  145. #endif
  146. #if defined(MBEDTLS_MD4_C)
  147.         case MBEDTLS_MD_MD4:
  148.             return( &mbedtls_md4_info );
  149. #endif
  150. #if defined(MBEDTLS_MD5_C)
  151.         case MBEDTLS_MD_MD5:
  152.             return( &mbedtls_md5_info );
  153. #endif
  154. #if defined(MBEDTLS_RIPEMD160_C)
  155.         case MBEDTLS_MD_RIPEMD160:
  156.             return( &mbedtls_ripemd160_info );
  157. #endif
  158. #if defined(MBEDTLS_SHA1_C)
  159.         case MBEDTLS_MD_SHA1:
  160.             return( &mbedtls_sha1_info );
  161. #endif
  162. #if defined(MBEDTLS_SHA256_C)
  163.         case MBEDTLS_MD_SHA224:
  164.             return( &mbedtls_sha224_info );
  165.         case MBEDTLS_MD_SHA256:
  166.             return( &mbedtls_sha256_info );
  167. #endif
  168. #if defined(MBEDTLS_SHA512_C)
  169.         case MBEDTLS_MD_SHA384:
  170.             return( &mbedtls_sha384_info );
  171.         case MBEDTLS_MD_SHA512:
  172.             return( &mbedtls_sha512_info );
  173. #endif
  174.         default:
  175.             return( NULL );
  176.     }
  177. }
  178.  
  179. void mbedtls_md_init( mbedtls_md_context_t *ctx )
  180. {
  181.     memset( ctx, 0, sizeof( mbedtls_md_context_t ) );
  182. }
  183.  
  184. void mbedtls_md_free( mbedtls_md_context_t *ctx )
  185. {
  186.     if( ctx == NULL || ctx->md_info == NULL )
  187.         return;
  188.  
  189.     if( ctx->md_ctx != NULL )
  190.         ctx->md_info->ctx_free_func( ctx->md_ctx );
  191.  
  192.     if( ctx->hmac_ctx != NULL )
  193.     {
  194.         mbedtls_platform_zeroize( ctx->hmac_ctx,
  195.                                   2 * ctx->md_info->block_size );
  196.         mbedtls_free( ctx->hmac_ctx );
  197.     }
  198.  
  199.     mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md_context_t ) );
  200. }
  201.  
  202. int mbedtls_md_clone( mbedtls_md_context_t *dst,
  203.                       const mbedtls_md_context_t *src )
  204. {
  205.     if( dst == NULL || dst->md_info == NULL ||
  206.         src == NULL || src->md_info == NULL ||
  207.         dst->md_info != src->md_info )
  208.     {
  209.         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
  210.     }
  211.  
  212.     dst->md_info->clone_func( dst->md_ctx, src->md_ctx );
  213.  
  214.     return( 0 );
  215. }
  216.  
  217. #if ! defined(MBEDTLS_DEPRECATED_REMOVED)
  218. int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info )
  219. {
  220.     return mbedtls_md_setup( ctx, md_info, 1 );
  221. }
  222. #endif
  223.  
  224. int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac )
  225. {
  226.     if( md_info == NULL || ctx == NULL )
  227.         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
  228.  
  229.     if( ( ctx->md_ctx = md_info->ctx_alloc_func() ) == NULL )
  230.         return( MBEDTLS_ERR_MD_ALLOC_FAILED );
  231.  
  232.     if( hmac != 0 )
  233.     {
  234.         ctx->hmac_ctx = mbedtls_calloc( 2, md_info->block_size );
  235.         if( ctx->hmac_ctx == NULL )
  236.         {
  237.             md_info->ctx_free_func( ctx->md_ctx );
  238.             return( MBEDTLS_ERR_MD_ALLOC_FAILED );
  239.         }
  240.     }
  241.  
  242.     ctx->md_info = md_info;
  243.  
  244.     return( 0 );
  245. }
  246.  
  247. int mbedtls_md_starts( mbedtls_md_context_t *ctx )
  248. {
  249.     if( ctx == NULL || ctx->md_info == NULL )
  250.         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
  251.  
  252.     return( ctx->md_info->starts_func( ctx->md_ctx ) );
  253. }
  254.  
  255. int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen )
  256. {
  257.     if( ctx == NULL || ctx->md_info == NULL )
  258.         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
  259.  
  260.     return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) );
  261. }
  262.  
  263. int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output )
  264. {
  265.     if( ctx == NULL || ctx->md_info == NULL )
  266.         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
  267.  
  268.     return( ctx->md_info->finish_func( ctx->md_ctx, output ) );
  269. }
  270.  
  271. int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen,
  272.             unsigned char *output )
  273. {
  274.     if( md_info == NULL )
  275.         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
  276.  
  277.     return( md_info->digest_func( input, ilen, output ) );
  278. }
  279.  
  280. #if defined(MBEDTLS_FS_IO)
  281. int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, unsigned char *output )
  282. {
  283.     int ret;
  284.     FILE *f;
  285.     size_t n;
  286.     mbedtls_md_context_t ctx;
  287.     unsigned char buf[1024];
  288.  
  289.     if( md_info == NULL )
  290.         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
  291.  
  292.     if( ( f = fopen( path, "rb" ) ) == NULL )
  293.         return( MBEDTLS_ERR_MD_FILE_IO_ERROR );
  294.  
  295.     mbedtls_md_init( &ctx );
  296.  
  297.     if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 )
  298.         goto cleanup;
  299.  
  300.     if( ( ret = md_info->starts_func( ctx.md_ctx ) ) != 0 )
  301.         goto cleanup;
  302.  
  303.     while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
  304.         if( ( ret = md_info->update_func( ctx.md_ctx, buf, n ) ) != 0 )
  305.             goto cleanup;
  306.  
  307.     if( ferror( f ) != 0 )
  308.         ret = MBEDTLS_ERR_MD_FILE_IO_ERROR;
  309.     else
  310.         ret = md_info->finish_func( ctx.md_ctx, output );
  311.  
  312. cleanup:
  313.     mbedtls_platform_zeroize( buf, sizeof( buf ) );
  314.     fclose( f );
  315.     mbedtls_md_free( &ctx );
  316.  
  317.     return( ret );
  318. }
  319. #endif /* MBEDTLS_FS_IO */
  320.  
  321. int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, size_t keylen )
  322. {
  323.     int ret;
  324.     unsigned char sum[MBEDTLS_MD_MAX_SIZE];
  325.     unsigned char *ipad, *opad;
  326.     size_t i;
  327.  
  328.     if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
  329.         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
  330.  
  331.     if( keylen > (size_t) ctx->md_info->block_size )
  332.     {
  333.         if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )
  334.             goto cleanup;
  335.         if( ( ret = ctx->md_info->update_func( ctx->md_ctx, key, keylen ) ) != 0 )
  336.             goto cleanup;
  337.         if( ( ret = ctx->md_info->finish_func( ctx->md_ctx, sum ) ) != 0 )
  338.             goto cleanup;
  339.  
  340.         keylen = ctx->md_info->size;
  341.         key = sum;
  342.     }
  343.  
  344.     ipad = (unsigned char *) ctx->hmac_ctx;
  345.     opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size;
  346.  
  347.     memset( ipad, 0x36, ctx->md_info->block_size );
  348.     memset( opad, 0x5C, ctx->md_info->block_size );
  349.  
  350.     for( i = 0; i < keylen; i++ )
  351.     {
  352.         ipad[i] = (unsigned char)( ipad[i] ^ key[i] );
  353.         opad[i] = (unsigned char)( opad[i] ^ key[i] );
  354.     }
  355.  
  356.     if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )
  357.         goto cleanup;
  358.     if( ( ret = ctx->md_info->update_func( ctx->md_ctx, ipad,
  359.                                            ctx->md_info->block_size ) ) != 0 )
  360.         goto cleanup;
  361.  
  362. cleanup:
  363.     mbedtls_platform_zeroize( sum, sizeof( sum ) );
  364.  
  365.     return( ret );
  366. }
  367.  
  368. int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen )
  369. {
  370.     if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
  371.         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
  372.  
  373.     return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) );
  374. }
  375.  
  376. int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output )
  377. {
  378.     int ret;
  379.     unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
  380.     unsigned char *opad;
  381.  
  382.     if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
  383.         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
  384.  
  385.     opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size;
  386.  
  387.     if( ( ret = ctx->md_info->finish_func( ctx->md_ctx, tmp ) ) != 0 )
  388.         return( ret );
  389.     if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )
  390.         return( ret );
  391.     if( ( ret = ctx->md_info->update_func( ctx->md_ctx, opad,
  392.                                            ctx->md_info->block_size ) ) != 0 )
  393.         return( ret );
  394.     if( ( ret = ctx->md_info->update_func( ctx->md_ctx, tmp,
  395.                                            ctx->md_info->size ) ) != 0 )
  396.         return( ret );
  397.     return( ctx->md_info->finish_func( ctx->md_ctx, output ) );
  398. }
  399.  
  400. int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx )
  401. {
  402.     int ret;
  403.     unsigned char *ipad;
  404.  
  405.     if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
  406.         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
  407.  
  408.     ipad = (unsigned char *) ctx->hmac_ctx;
  409.  
  410.     if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )
  411.         return( ret );
  412.     return( ctx->md_info->update_func( ctx->md_ctx, ipad,
  413.                                        ctx->md_info->block_size ) );
  414. }
  415.  
  416. int mbedtls_md_hmac( const mbedtls_md_info_t *md_info,
  417.                      const unsigned char *key, size_t keylen,
  418.                      const unsigned char *input, size_t ilen,
  419.                      unsigned char *output )
  420. {
  421.     mbedtls_md_context_t ctx;
  422.     int ret;
  423.  
  424.     if( md_info == NULL )
  425.         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
  426.  
  427.     mbedtls_md_init( &ctx );
  428.  
  429.     if( ( ret = mbedtls_md_setup( &ctx, md_info, 1 ) ) != 0 )
  430.         goto cleanup;
  431.  
  432.     if( ( ret = mbedtls_md_hmac_starts( &ctx, key, keylen ) ) != 0 )
  433.         goto cleanup;
  434.     if( ( ret = mbedtls_md_hmac_update( &ctx, input, ilen ) ) != 0 )
  435.         goto cleanup;
  436.     if( ( ret = mbedtls_md_hmac_finish( &ctx, output ) ) != 0 )
  437.         goto cleanup;
  438.  
  439. cleanup:
  440.     mbedtls_md_free( &ctx );
  441.  
  442.     return( ret );
  443. }
  444.  
  445. int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data )
  446. {
  447.     if( ctx == NULL || ctx->md_info == NULL )
  448.         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
  449.  
  450.     return( ctx->md_info->process_func( ctx->md_ctx, data ) );
  451. }
  452.  
  453. unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info )
  454. {
  455.     if( md_info == NULL )
  456.         return( 0 );
  457.  
  458.     return md_info->size;
  459. }
  460.  
  461. mbedtls_md_type_t mbedtls_md_get_type( const mbedtls_md_info_t *md_info )
  462. {
  463.     if( md_info == NULL )
  464.         return( MBEDTLS_MD_NONE );
  465.  
  466.     return md_info->type;
  467. }
  468.  
  469. const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info )
  470. {
  471.     if( md_info == NULL )
  472.         return( NULL );
  473.  
  474.     return md_info->name;
  475. }
  476.  
  477. #endif /* MBEDTLS_MD_C */
  478.