Line data Source code
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 library 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 : #include <gnutls_int.h>
24 : #include "int/tls1-prf.h"
25 : #include <nettle/hmac.h>
26 : #if ENABLE_GOST
27 : #include "gost/hmac-gost.h"
28 : #endif
29 :
30 : /*-
31 : * _gnutls_prf_raw:
32 : * @mac: the MAC algorithm to use, set to %GNUTLS_MAC_MD5_SHA1 for the TLS1.0 mac
33 : * @master_size: length of the @master variable.
34 : * @master: the master secret used in PRF computation
35 : * @label_size: length of the @label variable.
36 : * @label: label used in PRF computation, typically a short string.
37 : * @seed_size: length of the @seed variable.
38 : * @seed: optional extra data to seed the PRF with.
39 : * @outsize: size of pre-allocated output buffer to hold the output.
40 : * @out: pre-allocated buffer to hold the generated data.
41 : *
42 : * Apply the TLS Pseudo-Random-Function (PRF) on the master secret
43 : * and the provided data.
44 : *
45 : * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
46 : -*/
47 : int
48 36021 : _gnutls_prf_raw(gnutls_mac_algorithm_t mac,
49 : size_t master_size, const void *master,
50 : size_t label_size, const char *label,
51 : size_t seed_size, const uint8_t *seed, size_t outsize, char *out)
52 : {
53 36021 : int ret;
54 :
55 36021 : switch (mac) {
56 8311 : case GNUTLS_MAC_MD5_SHA1:
57 8311 : tls10_prf(master_size, (uint8_t*)master, label_size, label,
58 : seed_size, seed, outsize, (uint8_t*)out);
59 8311 : return 0;
60 13040 : case GNUTLS_MAC_SHA256:{
61 13040 : struct hmac_sha256_ctx ctx;
62 13040 : hmac_sha256_set_key(&ctx, master_size, (uint8_t*)master);
63 :
64 13040 : ret = tls12_prf(&ctx,
65 : (nettle_hash_update_func *)
66 : hmac_sha256_update,
67 : (nettle_hash_digest_func *)
68 : hmac_sha256_digest, SHA256_DIGEST_SIZE,
69 : label_size, label, seed_size,
70 : seed, outsize,
71 : (uint8_t*)out);
72 :
73 13040 : if (unlikely(ret != 1))
74 0 : return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
75 13040 : break;
76 : }
77 14366 : case GNUTLS_MAC_SHA384:{
78 14366 : struct hmac_sha384_ctx ctx;
79 14366 : hmac_sha384_set_key(&ctx, master_size, master);
80 :
81 14366 : ret = tls12_prf(&ctx,
82 : (nettle_hash_update_func *)
83 : hmac_sha384_update,
84 : (nettle_hash_digest_func *)
85 : hmac_sha384_digest, SHA384_DIGEST_SIZE,
86 : label_size, label, seed_size,
87 : seed, outsize,
88 : (uint8_t*)out);
89 :
90 14366 : if (unlikely(ret != 1))
91 0 : return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
92 14366 : break;
93 : }
94 : #if ENABLE_GOST
95 303 : case GNUTLS_MAC_STREEBOG_256:{
96 303 : struct hmac_streebog256_ctx ctx;
97 303 : hmac_streebog256_set_key(&ctx, master_size, master);
98 :
99 303 : ret = tls12_prf(&ctx,
100 : (nettle_hash_update_func *)
101 : hmac_streebog256_update,
102 : (nettle_hash_digest_func *)
103 : hmac_streebog256_digest, STREEBOG256_DIGEST_SIZE,
104 : label_size, label, seed_size,
105 : seed, outsize,
106 : (uint8_t*)out);
107 :
108 303 : if (unlikely(ret != 1))
109 0 : return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
110 303 : break;
111 : }
112 1 : case GNUTLS_MAC_STREEBOG_512:{
113 1 : struct hmac_streebog512_ctx ctx;
114 1 : hmac_streebog512_set_key(&ctx, master_size, master);
115 :
116 1 : ret = tls12_prf(&ctx,
117 : (nettle_hash_update_func *)
118 : hmac_streebog512_update,
119 : (nettle_hash_digest_func *)
120 : hmac_streebog512_digest, STREEBOG512_DIGEST_SIZE,
121 : label_size, label, seed_size,
122 : seed, outsize,
123 : (uint8_t*)out);
124 :
125 1 : if (unlikely(ret != 1))
126 0 : return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
127 1 : break;
128 : }
129 : #endif
130 0 : default:
131 0 : gnutls_assert();
132 0 : _gnutls_debug_log("unhandled PRF %s\n",
133 : gnutls_mac_get_name(mac));
134 : return GNUTLS_E_INVALID_REQUEST;
135 :
136 : }
137 :
138 : return 0;
139 : }
|