components/openssh/patches/036-fipsrandom.patch
branchs11u3-sru
changeset 7320 edeb951aa980
parent 7319 0753ecc76d4d
child 7340 16972dd9074c
equal deleted inserted replaced
7319:0753ecc76d4d 7320:edeb951aa980
     1 #
       
     2 # Replace arc4random* calls with FIPS compliant implementation in FIPS mode.
       
     3 #
       
     4 # Once libc:arc4random* are FIPS compliant (20816957), this patch will be
       
     5 # dropped.
       
     6 #
       
     7 # This is a temporary patch and is not intented for upstream contribution.
       
     8 #
       
     9 diff -pur old/misc.c new/misc.c
       
    10 --- old/misc.c
       
    11 +++ new/misc.c
       
    12 @@ -1164,3 +1164,87 @@ sock_set_v6only(int s)
       
    13  		error("setsockopt IPV6_V6ONLY: %s", strerror(errno));
       
    14  #endif
       
    15  }
       
    16 +
       
    17 +#ifdef ENABLE_OPENSSL_FIPS
       
    18 +/* cancel arc4random* -> fips_arc4random* defines from misc.h */
       
    19 +#undef	arc4random
       
    20 +#undef	arc4random_buf
       
    21 +#undef	arc4random_stir
       
    22 +#undef	arc4random_uniform
       
    23 +
       
    24 +/* FIPS compliant alternative for arc4random */
       
    25 +static uint32_t
       
    26 +fips_arc4random_impl()
       
    27 +{
       
    28 +	unsigned int r = 0;
       
    29 +
       
    30 +	if (RAND_bytes((unsigned char *)&r, sizeof (r)) <= 0) {
       
    31 +		fatal("RAND_bytes() failed. Aborting the process");
       
    32 +	}
       
    33 +
       
    34 +	return (r);
       
    35 +}
       
    36 +
       
    37 +uint32_t
       
    38 +fips_arc4random()
       
    39 +{
       
    40 +	if (!ssh_FIPS_mode())
       
    41 +		return arc4random();
       
    42 +	else
       
    43 +		return fips_arc4random_impl();
       
    44 +}
       
    45 +
       
    46 +/* implementation taken from openbsd-compat/arc4random.c */
       
    47 +void
       
    48 +fips_arc4random_buf(void *_buf, size_t n)
       
    49 +{
       
    50 +	size_t i;
       
    51 +	uint32_t r = 0;
       
    52 +	char *buf = (char *)_buf;
       
    53 +
       
    54 +	if (!ssh_FIPS_mode())
       
    55 +		return arc4random_buf(_buf, n);
       
    56 +
       
    57 +	for (i = 0; i < n; i++) {
       
    58 +		if (i % 4 == 0)
       
    59 +			r = fips_arc4random_impl();
       
    60 +		buf[i] = r & 0xff;
       
    61 +		r >>= 8;
       
    62 +	}
       
    63 +	explicit_bzero(&r, sizeof(r));
       
    64 +}
       
    65 +
       
    66 +void
       
    67 +fips_arc4random_stir(void)
       
    68 +{
       
    69 +	if (!ssh_FIPS_mode())
       
    70 +		return arc4random_stir();
       
    71 +}
       
    72 +
       
    73 +/* implementation taken from openbsd-compat/arc4random.c */
       
    74 +uint32_t
       
    75 +fips_arc4random_uniform(uint32_t upper_bound)
       
    76 +{
       
    77 +	uint32_t r, min;
       
    78 +
       
    79 +	if (upper_bound < 2)
       
    80 +		return 0;
       
    81 +
       
    82 +	/* 2**32 % x == (2**32 - x) % x */
       
    83 +	min = -upper_bound % upper_bound;
       
    84 +
       
    85 +	/*
       
    86 +	 * This could theoretically loop forever but each retry has
       
    87 +	 * p > 0.5 (worst case, usually far better) of selecting a
       
    88 +	 * number inside the range we need, so it should rarely need
       
    89 +	 * to re-roll.
       
    90 +	 */
       
    91 +	for (;;) {
       
    92 +		r = fips_arc4random_impl();
       
    93 +		if (r >= min)
       
    94 +			break;
       
    95 +	}
       
    96 +
       
    97 +	return r % upper_bound;
       
    98 +}
       
    99 +#endif /* ENABLE_OPENSSL_FIPS */
       
   100 diff -pur old/misc.h new/misc.h
       
   101 --- old/misc.h
       
   102 +++ new/misc.h
       
   103 @@ -140,4 +140,16 @@ char	*read_passphrase(const char *, int)
       
   104  int	 ask_permission(const char *, ...) __attribute__((format(printf, 1, 2)));
       
   105  int	 read_keyfile_line(FILE *, const char *, char *, size_t, u_long *);
       
   106  
       
   107 +#ifdef ENABLE_OPENSSL_FIPS
       
   108 +/* arc4random* FIPS alternatives */
       
   109 +uint32_t fips_arc4random(void);
       
   110 +void	 fips_arc4random_buf(void *, size_t);
       
   111 +void	 fips_arc4random_stir(void);
       
   112 +uint32_t fips_arc4random_uniform(uint32_t upper_bound);
       
   113 +#define	arc4random fips_arc4random
       
   114 +#define	arc4random_buf fips_arc4random_buf
       
   115 +#define	arc4random_stir fips_arc4random_stir
       
   116 +#define	arc4random_uniform fips_arc4random_uniform
       
   117 +#endif /* ENABLE_OPENSSL_FIPS */
       
   118 +
       
   119  #endif /* _MISC_H */