Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  *  Platform-specific and custom entropy polling functions
  3.  *
  4.  *  Copyright (C) 2006-2016, 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. #if defined(__linux__)
  25. /* Ensure that syscall() is available even when compiling with -std=c99 */
  26. #define _GNU_SOURCE
  27. #endif
  28.  
  29. #if !defined(MBEDTLS_CONFIG_FILE)
  30. #include "mbedtls/config.h"
  31. #else
  32. #include MBEDTLS_CONFIG_FILE
  33. #endif
  34.  
  35. #include <string.h>
  36.  
  37. /*rgimad*/
  38. #include <stdio.h>
  39.  
  40. #if defined(MBEDTLS_ENTROPY_C)
  41.  
  42. #include "mbedtls/entropy.h"
  43. #include "mbedtls/entropy_poll.h"
  44.  
  45. #if defined(MBEDTLS_TIMING_C)
  46. #include "mbedtls/timing.h"
  47. #endif
  48. #if defined(MBEDTLS_HAVEGE_C)
  49. #include "mbedtls/havege.h"
  50. #endif
  51. #if defined(MBEDTLS_ENTROPY_NV_SEED)
  52. #include "mbedtls/platform.h"
  53. #endif
  54.  
  55. #if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
  56.  
  57. #if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
  58.     !defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \
  59.     !defined(__HAIKU__)
  60. #error "Platform entropy sources only work on Unix and Windows, see MBEDTLS_NO_PLATFORM_ENTROPY in config.h"
  61. #endif
  62.  
  63. #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
  64.  
  65. #if !defined(_WIN32_WINNT)
  66. #define _WIN32_WINNT 0x0400
  67. #endif
  68. #include <windows.h>
  69. #include <wincrypt.h>
  70.  
  71. int mbedtls_platform_entropy_poll( void *data, unsigned char *output, size_t len,
  72.                            size_t *olen )
  73. {
  74.     HCRYPTPROV provider;
  75.     ((void) data);
  76.     *olen = 0;
  77.  
  78.     if( CryptAcquireContext( &provider, NULL, NULL,
  79.                               PROV_RSA_FULL, CRYPT_VERIFYCONTEXT ) == FALSE )
  80.     {
  81.         return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
  82.     }
  83.  
  84.     if( CryptGenRandom( provider, (DWORD) len, output ) == FALSE )
  85.     {
  86.         CryptReleaseContext( provider, 0 );
  87.         return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
  88.     }
  89.  
  90.     CryptReleaseContext( provider, 0 );
  91.     *olen = len;
  92.  
  93.     return( 0 );
  94. }
  95. #else /* _WIN32 && !EFIX64 && !EFI32 */
  96.  
  97. /*
  98.  * Test for Linux getrandom() support.
  99.  * Since there is no wrapper in the libc yet, use the generic syscall wrapper
  100.  * available in GNU libc and compatible libc's (eg uClibc).
  101.  */
  102. #if defined(__linux__) && defined(__GLIBC__)
  103. #include <unistd.h>
  104. #include <sys/syscall.h>
  105. #if defined(SYS_getrandom)
  106. #define HAVE_GETRANDOM
  107. #include <errno.h>
  108.  
  109. static int getrandom_wrapper( void *buf, size_t buflen, unsigned int flags )
  110. {
  111.     /* MemSan cannot understand that the syscall writes to the buffer */
  112. #if defined(__has_feature)
  113. #if __has_feature(memory_sanitizer)
  114.     memset( buf, 0, buflen );
  115. #endif
  116. #endif
  117.     return( syscall( SYS_getrandom, buf, buflen, flags ) );
  118. }
  119. #endif /* SYS_getrandom */
  120. #endif /* __linux__ */
  121.  
  122. #include <stdio.h>
  123.  
  124. int mbedtls_platform_entropy_poll( void *data,
  125.                            unsigned char *output, size_t len, size_t *olen )
  126. {
  127.     FILE *file;
  128.     size_t read_len;
  129.     int ret;
  130.     ((void) data);
  131.  
  132. #if defined(HAVE_GETRANDOM)
  133.     ret = getrandom_wrapper( output, len, 0 );
  134.     if( ret >= 0 )
  135.     {
  136.         *olen = ret;
  137.         return( 0 );
  138.     }
  139.     else if( errno != ENOSYS )
  140.         return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
  141.     /* Fall through if the system call isn't known. */
  142. #else
  143.     ((void) ret);
  144. #endif /* HAVE_GETRANDOM */
  145.  
  146.     *olen = 0;
  147.  
  148.     file = fopen( "/dev/urandom", "rb" );
  149.     if( file == NULL )
  150.         return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
  151.  
  152.     read_len = fread( output, 1, len, file );
  153.     if( read_len != len )
  154.     {
  155.         fclose( file );
  156.         return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
  157.     }
  158.  
  159.     fclose( file );
  160.     *olen = len;
  161.  
  162.     return( 0 );
  163. }
  164. #endif /* _WIN32 && !EFIX64 && !EFI32 */
  165. #endif /* !MBEDTLS_NO_PLATFORM_ENTROPY */
  166.  
  167.  
  168. /* -------------------------------------------------------------------------- */
  169.  
  170. /* entropy sources polls for KolibriOS */
  171. int mbedtls_sysfn_3_poll( void *data, unsigned char *output, size_t len, size_t *olen )
  172. {
  173.     unsigned long kos_time, bcd_sec, bcd_min, bcd_hr, secs, mins, hrs, seconds;
  174.     ((void) data);
  175.  
  176.     asm volatile("int $0x40" : "=a"(kos_time) : "a"(3));
  177.     bcd_sec = (kos_time >> 16);
  178.     bcd_min = ((kos_time & 0xFF00) >> 8);
  179.     bcd_hr = (kos_time & 0xFF);
  180.     secs = ((bcd_sec & 0xF0)>>4)*10 + (bcd_sec & 0x0F);
  181.     mins = ((bcd_min & 0xF0)>>4)*10 + (bcd_min & 0x0F);
  182.     hrs = ((bcd_hr & 0xF0)>>4)*10 + (bcd_hr & 0x0F);
  183.     seconds = hrs*3600 + mins*60 + secs;
  184.    
  185.     *olen = 0;
  186.     if( len < sizeof(unsigned long) )
  187.         return( 0 );
  188.  
  189.     memcpy( output, &seconds, sizeof(unsigned long) );
  190.     *olen = sizeof(unsigned long);
  191.  
  192.     return( 0 );
  193. }
  194.  
  195.  
  196. int mbedtls_sysfn_26_9_poll( void *data, unsigned char *output, size_t len, size_t *olen )
  197. {
  198.     unsigned long res;
  199.     ((void) data);
  200.  
  201.     asm volatile("int $0x40" : "=a"(res) : "a"(26), "b"(9));
  202.     *olen = 0;
  203.  
  204.     if( len < sizeof(unsigned long) )
  205.         return( 0 );
  206.  
  207.     memcpy( output, &res, sizeof(unsigned long) );
  208.     *olen = sizeof(unsigned long);
  209.  
  210.     return( 0 );
  211. }
  212.  
  213.  
  214. int mbedtls_sysfn_14_poll( void *data, unsigned char *output, size_t len, size_t *olen )
  215. {
  216.     unsigned long res;
  217.     ((void) data);
  218.  
  219.     asm volatile("int $0x40" : "=a"(res) : "a"(14));
  220.     *olen = 0;
  221.  
  222.     if( len < sizeof(unsigned long) )
  223.         return( 0 );
  224.  
  225.     memcpy( output, &res, sizeof(unsigned long) );
  226.     *olen = sizeof(unsigned long);
  227.  
  228.     return( 0 );
  229. }
  230.  
  231.  
  232. int mbedtls_sysfn_18_4_poll( void *data, unsigned char *output, size_t len, size_t *olen )
  233. {
  234.     unsigned long res;
  235.     ((void) data);
  236.  
  237.     asm volatile("int $0x40" : "=a"(res) : "a"(18), "b"(4));
  238.     *olen = 0;
  239.  
  240.     if( len < sizeof(unsigned long) )
  241.         return( 0 );
  242.  
  243.     memcpy( output, &res, sizeof(unsigned long) );
  244.     *olen = sizeof(unsigned long);
  245.  
  246.     return( 0 );
  247. }
  248.  
  249.  
  250. int mbedtls_sysfn_37_0_poll( void *data, unsigned char *output, size_t len, size_t *olen )
  251. {
  252.     unsigned long res;
  253.     ((void) data);
  254.  
  255.     asm volatile("int $0x40" : "=a"(res) : "a"(37), "b"(0));
  256.     *olen = 0;
  257.  
  258.     if( len < sizeof(unsigned long) )
  259.         return( 0 );
  260.  
  261.     memcpy( output, &res, sizeof(unsigned long) );
  262.     *olen = sizeof(unsigned long);
  263.  
  264.     return( 0 );
  265. }
  266.  
  267.  
  268. int mbedtls_sysfn_66_3_poll( void *data, unsigned char *output, size_t len, size_t *olen )
  269. {
  270.     unsigned long res;
  271.     ((void) data);
  272.  
  273.     asm volatile("int $0x40" : "=a"(res) : "a"(66), "b"(3));
  274.     *olen = 0;
  275.  
  276.     if( len < sizeof(unsigned long) )
  277.         return( 0 );
  278.  
  279.     memcpy( output, &res, sizeof(unsigned long) );
  280.     *olen = sizeof(unsigned long);
  281.  
  282.     return( 0 );
  283. }
  284.  
  285.  
  286. int mbedtls_sysfn_68_0_poll( void *data, unsigned char *output, size_t len, size_t *olen )
  287. {
  288.     unsigned long res;
  289.     ((void) data);
  290.  
  291.     asm volatile("int $0x40" : "=a"(res) : "a"(68), "b"(0));
  292.     *olen = 0;
  293.  
  294.     if( len < sizeof(unsigned long) )
  295.         return( 0 );
  296.  
  297.     memcpy( output, &res, sizeof(unsigned long) );
  298.     *olen = sizeof(unsigned long);
  299.  
  300.     return( 0 );
  301. }
  302.  
  303. /* -------------------------------------------------------------------------- */
  304.  
  305. #if defined(MBEDTLS_TEST_NULL_ENTROPY)
  306. int mbedtls_null_entropy_poll( void *data,
  307.                     unsigned char *output, size_t len, size_t *olen )
  308. {
  309.     ((void) data);
  310.     ((void) output);
  311.     *olen = 0;
  312.  
  313.     if( len < sizeof(unsigned char) )
  314.         return( 0 );
  315.  
  316.     *olen = sizeof(unsigned char);
  317.  
  318.     return( 0 );
  319. }
  320. #endif
  321.  
  322. #if defined(MBEDTLS_TIMING_C)
  323. int mbedtls_hardclock_poll( void *data,
  324.                     unsigned char *output, size_t len, size_t *olen )
  325. {
  326.     unsigned long timer = mbedtls_timing_hardclock();
  327.     ((void) data);
  328.     *olen = 0;
  329.  
  330.     if( len < sizeof(unsigned long) )
  331.         return( 0 );
  332.  
  333.     memcpy( output, &timer, sizeof(unsigned long) );
  334.     *olen = sizeof(unsigned long);
  335.  
  336.     return( 0 );
  337. }
  338. #endif /* MBEDTLS_TIMING_C */
  339.  
  340. #if defined(MBEDTLS_HAVEGE_C)
  341. int mbedtls_havege_poll( void *data,
  342.                  unsigned char *output, size_t len, size_t *olen )
  343. {
  344.     mbedtls_havege_state *hs = (mbedtls_havege_state *) data;
  345.     *olen = 0;
  346.  
  347.     if( mbedtls_havege_random( hs, output, len ) != 0 )
  348.         return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
  349.  
  350.     *olen = len;
  351.  
  352.     return( 0 );
  353. }
  354. #endif /* MBEDTLS_HAVEGE_C */
  355.  
  356. #if defined(MBEDTLS_ENTROPY_NV_SEED)
  357. int mbedtls_nv_seed_poll( void *data,
  358.                           unsigned char *output, size_t len, size_t *olen )
  359. {
  360.     unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
  361.     size_t use_len = MBEDTLS_ENTROPY_BLOCK_SIZE;
  362.     ((void) data);
  363.  
  364.     memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
  365.  
  366.     if( mbedtls_nv_seed_read( buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) < 0 )
  367.       return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
  368.  
  369.     if( len < use_len )
  370.       use_len = len;
  371.  
  372.     memcpy( output, buf, use_len );
  373.     *olen = use_len;
  374.  
  375.     return( 0 );
  376. }
  377. #endif /* MBEDTLS_ENTROPY_NV_SEED */
  378.  
  379. #endif /* MBEDTLS_ENTROPY_C */
  380.