return 0;
}
-static inline void swap_exts(extensions_t * exts1, extensions_t * exts2)
+static inline void swap_exts(extensions_t * exts, size_t index1, size_t index2)
{
- extensions_t temp = *exts1;
- *exts1 = *exts2;
- *exts2 = temp;
+ extensions_t temp = exts[index1];
+ exts[index1] = exts[index2];
+ exts[index2] = temp;
}
static
int shuffle_exts(extensions_t * exts, size_t size)
{
- /* generating random permutation of extensions */
- extensions_t rnd_n;
- for (size_t i = size - 1; i > 0; i--) {
- int ret = gnutls_rnd(GNUTLS_RND_RANDOM, (void *)&rnd_n,
- sizeof(extensions_t));
- if (ret < 0)
- return ret;
- extensions_t j = rnd_n % (i + 1);
- swap_exts(&exts[i], &exts[j]);
+ uint8_t permutation[MAX_EXT_TYPES];
+ size_t i;
+ int ret;
+
+ assert(size <= MAX_EXT_TYPES);
+
+ /* Generate random permutation, assuming MAX_EXT_TYPES <
+ * UINT8_MAX.
+ */
+ ret = gnutls_rnd(GNUTLS_RND_RANDOM, permutation, size);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ for (i = size - 1; i > 0; i--) {
+ extensions_t j = permutation[i] % (i + 1);
+ swap_exts(exts, i, j);
}
return 0;
int pos, ret;
size_t i;
hello_ext_ctx_st ctx;
+ /* To shuffle extension sending order */
+ extensions_t indices[MAX_EXT_TYPES];
msg &= GNUTLS_EXT_FLAG_SET_ONLY_FLAGS_MASK;
ret - 4);
}
- /* To shuffle extension sending order */
- extensions_t shuffled_exts[MAX_EXT_TYPES];
-
/* Initializing extensions array */
for (i = 0; i < MAX_EXT_TYPES; i++) {
- shuffled_exts[i] = i;
+ indices[i] = i;
}
- /* ordering dumbfw and pre_shared_key as last extensions */
- swap_exts(&shuffled_exts[MAX_EXT_TYPES - 2],
- &shuffled_exts[GNUTLS_EXTENSION_DUMBFW]);
- swap_exts(&shuffled_exts[MAX_EXT_TYPES - 1],
- &shuffled_exts[GNUTLS_EXTENSION_PRE_SHARED_KEY]);
-
- if (session->internals.priorities->no_exts_shuffle == 1)
- goto next;
+ if (!session->internals.priorities->no_shuffle_extensions) {
+ /* Ordering padding and pre_shared_key as last extensions */
+ swap_exts(indices, MAX_EXT_TYPES - 2, GNUTLS_EXTENSION_DUMBFW);
+ swap_exts(indices, MAX_EXT_TYPES - 1,
+ GNUTLS_EXTENSION_PRE_SHARED_KEY);
- ret = shuffle_exts(shuffled_exts, MAX_EXT_TYPES - 2);
- if (ret < 0)
- return gnutls_assert_val(ret);
+ ret = shuffle_exts(indices, MAX_EXT_TYPES - 2);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+ }
- next:
/* hello_ext_send() ensures we don't send duplicates, in case
* of overridden extensions */
- for (size_t r = 0; r < MAX_EXT_TYPES; r++) {
- i = shuffled_exts[r];
- if (!extfunc[i])
+ for (i = 0; i < MAX_EXT_TYPES; i++) {
+ size_t ii = indices[i];
+ if (!extfunc[ii])
continue;
- ctx.ext = extfunc[i];
- ret = _gnutls_extv_append(buf, extfunc[i]->tls_id,
+ ctx.ext = extfunc[ii];
+ ret = _gnutls_extv_append(buf, extfunc[ii]->tls_id,
&ctx, hello_ext_send);
if (ret < 0)
return gnutls_assert_val(ret);