LCOV - code coverage report
Current view: directory - src/shared/platform/posix - nacl_secure_random.c (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 51 31 60.8 %
Date: 2014-06-18 Functions: 0 0 -

       1                 : /*
       2                 :  * Copyright (c) 2012 The Native Client Authors. All rights reserved.
       3                 :  * Use of this source code is governed by a BSD-style license that can be
       4                 :  * found in the LICENSE file.
       5                 :  */
       6                 : 
       7                 : /*
       8                 :  * NaCl Service Runtime.  Secure RNG implementation.
       9                 :  */
      10                 : 
      11                 : #include <errno.h>
      12                 : #include <string.h>
      13                 : 
      14                 : #include <unistd.h>
      15                 : #include <sys/types.h>
      16                 : #include <sys/stat.h>
      17                 : #include <fcntl.h>
      18                 : 
      19                 : #include "native_client/src/shared/platform/nacl_check.h"
      20                 : #include "native_client/src/shared/platform/nacl_log.h"
      21                 : #include "native_client/src/shared/platform/nacl_secure_random.h"
      22                 : 
      23                 : #ifndef NACL_SECURE_RANDOM_SYSTEM_RANDOM_SOURCE
      24                 : # define NACL_SECURE_RANDOM_SYSTEM_RANDOM_SOURCE "/dev/urandom"
      25                 : #endif
      26                 : 
      27                 : static struct NaClSecureRngIfVtbl const kNaClSecureRngVtbl;
      28                 : 
      29                 : /* use -1 to ensure a fast failure if module initializer is not called */
      30                 : static int  urandom_d = -1;
      31                 : 
      32                 : /*
      33                 :  * This sets a /dev/urandom file descriptor for this module to use.
      34                 :  * This is for use inside outer sandboxes where opening /dev/urandom
      35                 :  * with open() does not work.
      36                 :  *
      37                 :  * This function should be called before NaClSecureRngModuleInit() so
      38                 :  * that we do not attempt to use open() inside the outer sandbox.
      39                 :  *
      40                 :  * This takes ownership of the file descriptor.
      41                 :  */
      42               0 : void NaClSecureRngModuleSetUrandomFd(int fd) {
      43               0 :   CHECK(urandom_d == -1);
      44               0 :   urandom_d = fd;
      45               0 : }
      46                 : 
      47                 : void NaClSecureRngModuleInit(void) {
      48                 :   /*
      49                 :    * Check whether we have already been initialised via
      50                 :    * NaClSecureRngModuleSetUrandomFd().
      51                 :    */
      52             331 :   if (urandom_d != -1) {
      53               1 :     return;
      54                 :   }
      55                 : 
      56             330 :   urandom_d = open(NACL_SECURE_RANDOM_SYSTEM_RANDOM_SOURCE, O_RDONLY, 0);
      57             330 :   if (-1 == urandom_d) {
      58               0 :     NaClLog(LOG_FATAL, "Cannot open system random source %s\n",
      59                 :             NACL_SECURE_RANDOM_SYSTEM_RANDOM_SOURCE);
      60               0 :   }
      61             331 : }
      62                 : 
      63                 : void NaClSecureRngModuleFini(void) {
      64              53 :   if (urandom_d != -1) {
      65              53 :     if (close(urandom_d) != 0) {
      66               0 :       NaClLog(LOG_FATAL,
      67                 :               "NaClSecureRngModuleFini: close() failed with errno %d\n",
      68               0 :               errno);
      69               0 :     }
      70              53 :     urandom_d = -1;
      71              53 :   }
      72              53 : }
      73                 : 
      74             628 : int NaClSecureRngCtor(struct NaClSecureRng *self) {
      75             628 :   self->base.vtbl = &kNaClSecureRngVtbl;
      76             628 :   self->nvalid = 0;
      77             628 :   return 1;
      78                 : }
      79                 : 
      80               0 : int NaClSecureRngTestingCtor(struct NaClSecureRng *self,
      81               0 :                              uint8_t              *seed_material,
      82               0 :                              size_t               seed_bytes) {
      83               0 :   UNREFERENCED_PARAMETER(self);
      84               0 :   UNREFERENCED_PARAMETER(seed_material);
      85               0 :   UNREFERENCED_PARAMETER(seed_bytes);
      86               0 :   return 0;
      87                 : }
      88                 : 
      89              54 : static void NaClSecureRngDtor(struct NaClSecureRngIf *vself) {
      90              54 :   struct NaClSecureRng *self = (struct NaClSecureRng *) vself;
      91             162 :   memset(self->buf, 0, sizeof self->buf);
      92              54 :   vself->vtbl = NULL;
      93              54 :   return;
      94                 : }
      95                 : 
      96             307 : static void NaClSecureRngFilbuf(struct NaClSecureRng *self) {
      97             921 :   VCHECK(-1 != urandom_d,
      98                 :          ("NaClSecureRngCtor: random descriptor invalid;"
      99                 :           " module initialization failed?\n"));
     100             307 :   self->nvalid = read(urandom_d, self->buf, sizeof self->buf);
     101             307 :   if (self->nvalid <= 0) {
     102               0 :     NaClLog(LOG_FATAL, "NaClSecureRngFilbuf failed, read returned %d\n",
     103                 :             self->nvalid);
     104               0 :   }
     105             307 : }
     106                 : 
     107           31314 : static uint8_t NaClSecureRngGenByte(struct NaClSecureRngIf *vself) {
     108           31314 :   struct NaClSecureRng *self = (struct NaClSecureRng *) vself;
     109                 : 
     110           31314 :   if (0 > self->nvalid) {
     111               0 :     NaClLog(LOG_FATAL,
     112                 :             "NaClSecureRngGenByte: illegal buffer state, nvalid = %d\n",
     113                 :             self->nvalid);
     114               0 :   }
     115           31314 :   if (0 == self->nvalid) {
     116             307 :     NaClSecureRngFilbuf(self);
     117             307 :   }
     118                 :   /* 0 < self->nvalid <= sizeof self->buf */
     119           31314 :   return self->buf[--self->nvalid];
     120                 : }
     121                 : 
     122                 : static struct NaClSecureRngIfVtbl const kNaClSecureRngVtbl = {
     123                 :   NaClSecureRngDtor,
     124                 :   NaClSecureRngGenByte,
     125                 :   NaClSecureRngDefaultGenUint32,
     126                 :   NaClSecureRngDefaultGenBytes,
     127                 :   NaClSecureRngDefaultUniform,
     128                 : };

Generated by: LCOV version 1.7