Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  *  PKCS#12 Personal Information Exchange Syntax
  3.  *
  4.  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  5.  *  SPDX-License-Identifier: GPL-2.0
  6.  *
  7.  *  This program is free software; you can redistribute it and/or modify
  8.  *  it under the terms of the GNU General Public License as published by
  9.  *  the Free Software Foundation; either version 2 of the License, or
  10.  *  (at your option) any later version.
  11.  *
  12.  *  This program is distributed in the hope that it will be useful,
  13.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  *  GNU General Public License for more details.
  16.  *
  17.  *  You should have received a copy of the GNU General Public License along
  18.  *  with this program; if not, write to the Free Software Foundation, Inc.,
  19.  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  20.  *
  21.  *  This file is part of mbed TLS (https://tls.mbed.org)
  22.  */
  23. /*
  24.  *  The PKCS #12 Personal Information Exchange Syntax Standard v1.1
  25.  *
  26.  *  http://www.rsa.com/rsalabs/pkcs/files/h11301-wp-pkcs-12v1-1-personal-information-exchange-syntax.pdf
  27.  *  ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-12/pkcs-12v1-1.asn
  28.  */
  29.  
  30. #if !defined(MBEDTLS_CONFIG_FILE)
  31. #include "mbedtls/config.h"
  32. #else
  33. #include MBEDTLS_CONFIG_FILE
  34. #endif
  35.  
  36. #if defined(MBEDTLS_PKCS12_C)
  37.  
  38. #include "mbedtls/pkcs12.h"
  39. #include "mbedtls/asn1.h"
  40. #include "mbedtls/cipher.h"
  41. #include "mbedtls/platform_util.h"
  42.  
  43. #include <string.h>
  44.  
  45. #if defined(MBEDTLS_ARC4_C)
  46. #include "mbedtls/arc4.h"
  47. #endif
  48.  
  49. #if defined(MBEDTLS_DES_C)
  50. #include "mbedtls/des.h"
  51. #endif
  52.  
  53. #if defined(MBEDTLS_ASN1_PARSE_C)
  54.  
  55. static int pkcs12_parse_pbe_params( mbedtls_asn1_buf *params,
  56.                                     mbedtls_asn1_buf *salt, int *iterations )
  57. {
  58.     int ret;
  59.     unsigned char **p = &params->p;
  60.     const unsigned char *end = params->p + params->len;
  61.  
  62.     /*
  63.      *  pkcs-12PbeParams ::= SEQUENCE {
  64.      *    salt          OCTET STRING,
  65.      *    iterations    INTEGER
  66.      *  }
  67.      *
  68.      */
  69.     if( params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) )
  70.         return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT +
  71.                 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
  72.  
  73.     if( ( ret = mbedtls_asn1_get_tag( p, end, &salt->len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
  74.         return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT + ret );
  75.  
  76.     salt->p = *p;
  77.     *p += salt->len;
  78.  
  79.     if( ( ret = mbedtls_asn1_get_int( p, end, iterations ) ) != 0 )
  80.         return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT + ret );
  81.  
  82.     if( *p != end )
  83.         return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT +
  84.                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
  85.  
  86.     return( 0 );
  87. }
  88.  
  89. #define PKCS12_MAX_PWDLEN 128
  90.  
  91. static int pkcs12_pbe_derive_key_iv( mbedtls_asn1_buf *pbe_params, mbedtls_md_type_t md_type,
  92.                                      const unsigned char *pwd,  size_t pwdlen,
  93.                                      unsigned char *key, size_t keylen,
  94.                                      unsigned char *iv,  size_t ivlen )
  95. {
  96.     int ret, iterations = 0;
  97.     mbedtls_asn1_buf salt;
  98.     size_t i;
  99.     unsigned char unipwd[PKCS12_MAX_PWDLEN * 2 + 2];
  100.  
  101.     if( pwdlen > PKCS12_MAX_PWDLEN )
  102.         return( MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA );
  103.  
  104.     memset( &salt, 0, sizeof(mbedtls_asn1_buf) );
  105.     memset( &unipwd, 0, sizeof(unipwd) );
  106.  
  107.     if( ( ret = pkcs12_parse_pbe_params( pbe_params, &salt,
  108.                                          &iterations ) ) != 0 )
  109.         return( ret );
  110.  
  111.     for( i = 0; i < pwdlen; i++ )
  112.         unipwd[i * 2 + 1] = pwd[i];
  113.  
  114.     if( ( ret = mbedtls_pkcs12_derivation( key, keylen, unipwd, pwdlen * 2 + 2,
  115.                                    salt.p, salt.len, md_type,
  116.                                    MBEDTLS_PKCS12_DERIVE_KEY, iterations ) ) != 0 )
  117.     {
  118.         return( ret );
  119.     }
  120.  
  121.     if( iv == NULL || ivlen == 0 )
  122.         return( 0 );
  123.  
  124.     if( ( ret = mbedtls_pkcs12_derivation( iv, ivlen, unipwd, pwdlen * 2 + 2,
  125.                                    salt.p, salt.len, md_type,
  126.                                    MBEDTLS_PKCS12_DERIVE_IV, iterations ) ) != 0 )
  127.     {
  128.         return( ret );
  129.     }
  130.     return( 0 );
  131. }
  132.  
  133. #undef PKCS12_MAX_PWDLEN
  134.  
  135. int mbedtls_pkcs12_pbe_sha1_rc4_128( mbedtls_asn1_buf *pbe_params, int mode,
  136.                              const unsigned char *pwd,  size_t pwdlen,
  137.                              const unsigned char *data, size_t len,
  138.                              unsigned char *output )
  139. {
  140. #if !defined(MBEDTLS_ARC4_C)
  141.     ((void) pbe_params);
  142.     ((void) mode);
  143.     ((void) pwd);
  144.     ((void) pwdlen);
  145.     ((void) data);
  146.     ((void) len);
  147.     ((void) output);
  148.     return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE );
  149. #else
  150.     int ret;
  151.     unsigned char key[16];
  152.     mbedtls_arc4_context ctx;
  153.     ((void) mode);
  154.  
  155.     mbedtls_arc4_init( &ctx );
  156.  
  157.     if( ( ret = pkcs12_pbe_derive_key_iv( pbe_params, MBEDTLS_MD_SHA1,
  158.                                           pwd, pwdlen,
  159.                                           key, 16, NULL, 0 ) ) != 0 )
  160.     {
  161.         return( ret );
  162.     }
  163.  
  164.     mbedtls_arc4_setup( &ctx, key, 16 );
  165.     if( ( ret = mbedtls_arc4_crypt( &ctx, len, data, output ) ) != 0 )
  166.         goto exit;
  167.  
  168. exit:
  169.     mbedtls_platform_zeroize( key, sizeof( key ) );
  170.     mbedtls_arc4_free( &ctx );
  171.  
  172.     return( ret );
  173. #endif /* MBEDTLS_ARC4_C */
  174. }
  175.  
  176. int mbedtls_pkcs12_pbe( mbedtls_asn1_buf *pbe_params, int mode,
  177.                 mbedtls_cipher_type_t cipher_type, mbedtls_md_type_t md_type,
  178.                 const unsigned char *pwd,  size_t pwdlen,
  179.                 const unsigned char *data, size_t len,
  180.                 unsigned char *output )
  181. {
  182.     int ret, keylen = 0;
  183.     unsigned char key[32];
  184.     unsigned char iv[16];
  185.     const mbedtls_cipher_info_t *cipher_info;
  186.     mbedtls_cipher_context_t cipher_ctx;
  187.     size_t olen = 0;
  188.  
  189.     cipher_info = mbedtls_cipher_info_from_type( cipher_type );
  190.     if( cipher_info == NULL )
  191.         return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE );
  192.  
  193.     keylen = cipher_info->key_bitlen / 8;
  194.  
  195.     if( ( ret = pkcs12_pbe_derive_key_iv( pbe_params, md_type, pwd, pwdlen,
  196.                                           key, keylen,
  197.                                           iv, cipher_info->iv_size ) ) != 0 )
  198.     {
  199.         return( ret );
  200.     }
  201.  
  202.     mbedtls_cipher_init( &cipher_ctx );
  203.  
  204.     if( ( ret = mbedtls_cipher_setup( &cipher_ctx, cipher_info ) ) != 0 )
  205.         goto exit;
  206.  
  207.     if( ( ret = mbedtls_cipher_setkey( &cipher_ctx, key, 8 * keylen, (mbedtls_operation_t) mode ) ) != 0 )
  208.         goto exit;
  209.  
  210.     if( ( ret = mbedtls_cipher_set_iv( &cipher_ctx, iv, cipher_info->iv_size ) ) != 0 )
  211.         goto exit;
  212.  
  213.     if( ( ret = mbedtls_cipher_reset( &cipher_ctx ) ) != 0 )
  214.         goto exit;
  215.  
  216.     if( ( ret = mbedtls_cipher_update( &cipher_ctx, data, len,
  217.                                 output, &olen ) ) != 0 )
  218.     {
  219.         goto exit;
  220.     }
  221.  
  222.     if( ( ret = mbedtls_cipher_finish( &cipher_ctx, output + olen, &olen ) ) != 0 )
  223.         ret = MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH;
  224.  
  225. exit:
  226.     mbedtls_platform_zeroize( key, sizeof( key ) );
  227.     mbedtls_platform_zeroize( iv,  sizeof( iv  ) );
  228.     mbedtls_cipher_free( &cipher_ctx );
  229.  
  230.     return( ret );
  231. }
  232.  
  233. #endif /* MBEDTLS_ASN1_PARSE_C */
  234.  
  235. static void pkcs12_fill_buffer( unsigned char *data, size_t data_len,
  236.                                 const unsigned char *filler, size_t fill_len )
  237. {
  238.     unsigned char *p = data;
  239.     size_t use_len;
  240.  
  241.     while( data_len > 0 )
  242.     {
  243.         use_len = ( data_len > fill_len ) ? fill_len : data_len;
  244.         memcpy( p, filler, use_len );
  245.         p += use_len;
  246.         data_len -= use_len;
  247.     }
  248. }
  249.  
  250. int mbedtls_pkcs12_derivation( unsigned char *data, size_t datalen,
  251.                        const unsigned char *pwd, size_t pwdlen,
  252.                        const unsigned char *salt, size_t saltlen,
  253.                        mbedtls_md_type_t md_type, int id, int iterations )
  254. {
  255.     int ret;
  256.     unsigned int j;
  257.  
  258.     unsigned char diversifier[128];
  259.     unsigned char salt_block[128], pwd_block[128], hash_block[128];
  260.     unsigned char hash_output[MBEDTLS_MD_MAX_SIZE];
  261.     unsigned char *p;
  262.     unsigned char c;
  263.  
  264.     size_t hlen, use_len, v, i;
  265.  
  266.     const mbedtls_md_info_t *md_info;
  267.     mbedtls_md_context_t md_ctx;
  268.  
  269.     // This version only allows max of 64 bytes of password or salt
  270.     if( datalen > 128 || pwdlen > 64 || saltlen > 64 )
  271.         return( MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA );
  272.  
  273.     md_info = mbedtls_md_info_from_type( md_type );
  274.     if( md_info == NULL )
  275.         return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE );
  276.  
  277.     mbedtls_md_init( &md_ctx );
  278.  
  279.     if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
  280.         return( ret );
  281.     hlen = mbedtls_md_get_size( md_info );
  282.  
  283.     if( hlen <= 32 )
  284.         v = 64;
  285.     else
  286.         v = 128;
  287.  
  288.     memset( diversifier, (unsigned char) id, v );
  289.  
  290.     pkcs12_fill_buffer( salt_block, v, salt, saltlen );
  291.     pkcs12_fill_buffer( pwd_block,  v, pwd,  pwdlen  );
  292.  
  293.     p = data;
  294.     while( datalen > 0 )
  295.     {
  296.         // Calculate hash( diversifier || salt_block || pwd_block )
  297.         if( ( ret = mbedtls_md_starts( &md_ctx ) ) != 0 )
  298.             goto exit;
  299.  
  300.         if( ( ret = mbedtls_md_update( &md_ctx, diversifier, v ) ) != 0 )
  301.             goto exit;
  302.  
  303.         if( ( ret = mbedtls_md_update( &md_ctx, salt_block, v ) ) != 0 )
  304.             goto exit;
  305.  
  306.         if( ( ret = mbedtls_md_update( &md_ctx, pwd_block, v ) ) != 0 )
  307.             goto exit;
  308.  
  309.         if( ( ret = mbedtls_md_finish( &md_ctx, hash_output ) ) != 0 )
  310.             goto exit;
  311.  
  312.         // Perform remaining ( iterations - 1 ) recursive hash calculations
  313.         for( i = 1; i < (size_t) iterations; i++ )
  314.         {
  315.             if( ( ret = mbedtls_md( md_info, hash_output, hlen, hash_output ) ) != 0 )
  316.                 goto exit;
  317.         }
  318.  
  319.         use_len = ( datalen > hlen ) ? hlen : datalen;
  320.         memcpy( p, hash_output, use_len );
  321.         datalen -= use_len;
  322.         p += use_len;
  323.  
  324.         if( datalen == 0 )
  325.             break;
  326.  
  327.         // Concatenating copies of hash_output into hash_block (B)
  328.         pkcs12_fill_buffer( hash_block, v, hash_output, hlen );
  329.  
  330.         // B += 1
  331.         for( i = v; i > 0; i-- )
  332.             if( ++hash_block[i - 1] != 0 )
  333.                 break;
  334.  
  335.         // salt_block += B
  336.         c = 0;
  337.         for( i = v; i > 0; i-- )
  338.         {
  339.             j = salt_block[i - 1] + hash_block[i - 1] + c;
  340.             c = (unsigned char) (j >> 8);
  341.             salt_block[i - 1] = j & 0xFF;
  342.         }
  343.  
  344.         // pwd_block  += B
  345.         c = 0;
  346.         for( i = v; i > 0; i-- )
  347.         {
  348.             j = pwd_block[i - 1] + hash_block[i - 1] + c;
  349.             c = (unsigned char) (j >> 8);
  350.             pwd_block[i - 1] = j & 0xFF;
  351.         }
  352.     }
  353.  
  354.     ret = 0;
  355.  
  356. exit:
  357.     mbedtls_platform_zeroize( salt_block, sizeof( salt_block ) );
  358.     mbedtls_platform_zeroize( pwd_block, sizeof( pwd_block ) );
  359.     mbedtls_platform_zeroize( hash_block, sizeof( hash_block ) );
  360.     mbedtls_platform_zeroize( hash_output, sizeof( hash_output ) );
  361.  
  362.     mbedtls_md_free( &md_ctx );
  363.  
  364.     return( ret );
  365. }
  366.  
  367. #endif /* MBEDTLS_PKCS12_C */
  368.