Coverage Report

Created: 2025-07-12 06:06

/src/strongswan/src/libstrongswan/plugins/random/random_rng.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2005-2008 Martin Willi
3
 * Copyright (C) 2005 Jan Hutter
4
 *
5
 * Copyright (C) secunet Security Networks AG
6
 *
7
 * This program is free software; you can redistribute it and/or modify it
8
 * under the terms of the GNU General Public License as published by the
9
 * Free Software Foundation; either version 2 of the License, or (at your
10
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
11
 *
12
 * This program is distributed in the hope that it will be useful, but
13
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15
 * for more details.
16
 */
17
18
#include <string.h>
19
#include <unistd.h>
20
#include <errno.h>
21
#include <utils/debug.h>
22
23
#include "random_rng.h"
24
#include "random_plugin.h"
25
26
typedef struct private_random_rng_t private_random_rng_t;
27
28
/**
29
 * Private data of an random_rng_t object.
30
 */
31
struct private_random_rng_t {
32
33
  /**
34
   * Public random_rng_t interface.
35
   */
36
  random_rng_t public;
37
38
  /**
39
   * random device, depends on quality
40
   */
41
  int fd;
42
};
43
44
METHOD(rng_t, get_bytes, bool,
45
  private_random_rng_t *this, size_t bytes, uint8_t *buffer)
46
0
{
47
0
  size_t done;
48
0
  ssize_t got;
49
50
0
  done = 0;
51
52
0
  while (done < bytes)
53
0
  {
54
0
    got = read(this->fd, buffer + done, bytes - done);
55
0
    if (got <= 0)
56
0
    {
57
0
      DBG1(DBG_LIB, "reading from random FD %d failed: %s, retrying...",
58
0
         this->fd, strerror(errno));
59
0
      sleep(1);
60
0
      continue;
61
0
    }
62
0
    done += got;
63
0
  }
64
0
  return TRUE;
65
0
}
66
67
METHOD(rng_t, allocate_bytes, bool,
68
  private_random_rng_t *this, size_t bytes, chunk_t *chunk)
69
0
{
70
0
  *chunk = chunk_alloc(bytes);
71
0
  get_bytes(this, chunk->len, chunk->ptr);
72
0
  return TRUE;
73
0
}
74
75
METHOD(rng_t, destroy, void,
76
  private_random_rng_t *this)
77
0
{
78
0
  free(this);
79
0
}
80
81
/*
82
 * Described in header.
83
 */
84
random_rng_t *random_rng_create(rng_quality_t quality)
85
0
{
86
0
  private_random_rng_t *this;
87
88
0
  INIT(this,
89
0
    .public = {
90
0
      .rng = {
91
0
        .get_bytes = _get_bytes,
92
0
        .allocate_bytes = _allocate_bytes,
93
0
        .destroy = _destroy,
94
0
      },
95
0
    },
96
0
  );
97
98
0
  switch (quality)
99
0
  {
100
0
    case RNG_TRUE:
101
0
      this->fd = random_plugin_get_dev_random();
102
0
      break;
103
0
    case RNG_STRONG:
104
0
      this->fd = random_plugin_get_strong_equals_true() ?
105
0
              random_plugin_get_dev_random() :
106
0
              random_plugin_get_dev_urandom();
107
0
      break;
108
0
    case RNG_WEAK:
109
0
    default:
110
0
      this->fd = random_plugin_get_dev_urandom();
111
0
      break;
112
0
  }
113
114
0
  return &this->public;
115
0
}
116