Coverage Report

Created: 2023-03-26 08:33

/src/gnutls/lib/nettle/int/tls1-prf.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2017 Red Hat, Inc.
3
 *
4
 * Author: Nikos Mavrogiannopoulos
5
 *
6
 * This file is part of GnuTLS.
7
 *
8
 * The GnuTLS is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public License
10
 * as published by the Free Software Foundation; either version 2.1 of
11
 * the License, or (at your option) any later version.
12
 *
13
 * This library is distributed in the hope that it will be useful, but
14
 * WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>
20
 *
21
 */
22
23
/* Functions for the TLS PRF handling.
24
 */
25
26
#if HAVE_CONFIG_H
27
# include <config.h>
28
#endif
29
30
#include <gnutls_int.h>
31
32
#include <stdlib.h>
33
#include <string.h>
34
35
#include <nettle/hmac.h>
36
#include <nettle/memxor.h>
37
#include "int/tls1-prf.h"
38
#include <nettle/sha1.h>
39
#include <nettle/md5.h>
40
41
/* The RFC2246 P_hash() function. The mac_ctx is expected to
42
 * be initialized and key set to be the secret key.
43
 */
44
static void
45
P_hash(void *mac_ctx,
46
       nettle_hash_update_func * update,
47
       nettle_hash_digest_func * digest,
48
       size_t digest_size,
49
       size_t seed_size, const uint8_t * seed,
50
       size_t label_size, const char *label, size_t dst_length, uint8_t * dst)
51
0
{
52
0
  uint8_t Atmp[MAX_HASH_SIZE];
53
0
  ssize_t left;
54
0
  unsigned started = 0;
55
56
  /* round up */
57
0
  left = dst_length;
58
59
0
  while (left > 0) {
60
0
    if (started == 0) { /* A(0) */
61
0
      update(mac_ctx, label_size, (const uint8_t *)label);  /* hash label */
62
0
      update(mac_ctx, seed_size, seed);
63
0
      started = 1;
64
0
    } else {
65
0
      update(mac_ctx, digest_size, Atmp);
66
0
    }
67
0
    digest(mac_ctx, digest_size, Atmp); /* store A(i) */
68
69
0
    update(mac_ctx, digest_size, Atmp); /* hash A(i) */
70
0
    update(mac_ctx, label_size, (const uint8_t *)label);  /* hash label */
71
0
    update(mac_ctx, seed_size, seed); /* hash seed */
72
73
0
    if (left < (ssize_t) digest_size)
74
0
      digest_size = left;
75
76
0
    digest(mac_ctx, digest_size, dst);
77
78
0
    left -= digest_size;
79
0
    dst += digest_size;
80
0
  }
81
82
0
  return;
83
0
}
84
85
int
86
tls10_prf(size_t secret_size, const uint8_t * secret,
87
    size_t label_size, const char *label,
88
    size_t seed_size, const uint8_t * seed, size_t length, uint8_t * dst)
89
0
{
90
0
  int l_s;
91
0
  const uint8_t *s1, *s2;
92
0
  struct hmac_md5_ctx md5_ctx;
93
0
  struct hmac_sha1_ctx sha1_ctx;
94
0
  uint8_t o1[MAX_PRF_BYTES];
95
96
0
  if (length > MAX_PRF_BYTES)
97
0
    return 0;
98
99
0
  l_s = secret_size / 2;
100
0
  s1 = &secret[0];
101
0
  s2 = &secret[l_s];
102
0
  if (secret_size % 2 != 0) {
103
0
    l_s++;
104
0
  }
105
106
0
  hmac_md5_set_key(&md5_ctx, l_s, s1);
107
108
0
  P_hash(&md5_ctx, (nettle_hash_update_func *) hmac_md5_update,
109
0
         (nettle_hash_digest_func *) hmac_md5_digest,
110
0
         MD5_DIGEST_SIZE, seed_size, seed, label_size, label, length, o1);
111
112
0
  hmac_sha1_set_key(&sha1_ctx, l_s, s2);
113
114
0
  P_hash(&sha1_ctx, (nettle_hash_update_func *) hmac_sha1_update,
115
0
         (nettle_hash_digest_func *) hmac_sha1_digest,
116
0
         SHA1_DIGEST_SIZE,
117
0
         seed_size, seed, label_size, label, length, dst);
118
119
0
  memxor(dst, o1, length);
120
121
0
  return 1;
122
0
}
123
124
/*-
125
 * tls12_prf:
126
 * @mac_ctx: a MAC context initialized with key being the secret
127
 * @update: a MAC update function
128
 * @digest: a MAC digest function
129
 * @digest_size: the MAC output size
130
 * @label_size: the size of the label
131
 * @label: the label to apply
132
 * @seed_size: the seed size
133
 * @seed: the seed
134
 * @length: size of desired PRF output
135
 * @dst: the location to store output
136
 *
137
 * The TLS 1.2 Pseudo-Random-Function (PRF).
138
 *
139
 * Returns: zero on failure, non zero on success.
140
 -*/
141
int
142
tls12_prf(void *mac_ctx,
143
    nettle_hash_update_func * update,
144
    nettle_hash_digest_func * digest,
145
    size_t digest_size,
146
    size_t label_size, const char *label,
147
    size_t seed_size, const uint8_t * seed, size_t length, uint8_t * dst)
148
0
{
149
0
  P_hash(mac_ctx, update, digest, digest_size,
150
0
         seed_size, seed, label_size, label, length, dst);
151
152
0
  return 1;
153
0
}