summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaiki Ueno <ueno@gnu.org>2022-10-17 12:29:17 +0000
committerDaiki Ueno <ueno@gnu.org>2022-10-17 12:29:17 +0000
commitacc7a7a0492f0153a61e510f45f3a55175e404d7 (patch)
tree458b1597c379b440db7b0d0152b2307cd664aca9
parentf5dcbdb46df52458e3756193c2a23bf558a3ecfd (diff)
parent2d9c97a284482a78944375d8b38252f23c767ba7 (diff)
downloadgnutls-acc7a7a0492f0153a61e510f45f3a55175e404d7.tar.gz
Merge branch 'wip/dueno/symkey-limit' into 'master'
fips: mark symmetric key crypto operations with short key and output sizes non-approved See merge request gnutls/gnutls!1643
-rw-r--r--.gitignore2
-rw-r--r--lib/crypto-api.c31
-rw-r--r--lib/fips.h16
-rw-r--r--tests/dh-compute.c36
-rw-r--r--tests/fips-rsa-sizes.c24
-rw-r--r--tests/fips-test.c76
-rw-r--r--tests/kdf-api.c69
-rw-r--r--tests/pkcs12_encode.c24
-rw-r--r--tests/privkey-keygen.c24
-rw-r--r--tests/utils.h58
10 files changed, 199 insertions, 161 deletions
diff --git a/.gitignore b/.gitignore
index 0a5acb5b2b..3b4e4ae961 100644
--- a/.gitignore
+++ b/.gitignore
@@ -419,7 +419,7 @@ tests/fallback-scsv
tests/finished
tests/fips-mode-pthread
tests/fips-override-test
-tests/fips-rsa-key-sizes
+tests/fips-rsa-sizes
tests/fips-test
tests/gc
tests/global-init
diff --git a/lib/crypto-api.c b/lib/crypto-api.c
index 7f81011c42..9f7e18db11 100644
--- a/lib/crypto-api.c
+++ b/lib/crypto-api.c
@@ -1056,6 +1056,7 @@ gnutls_hash_hd_t gnutls_hash_copy(gnutls_hash_hd_t handle)
int gnutls_key_generate(gnutls_datum_t * key, unsigned int key_size)
{
int ret;
+ bool not_approved = false;
FAIL_IF_LIB_ERROR;
@@ -1072,17 +1073,31 @@ int gnutls_key_generate(gnutls_datum_t * key, unsigned int key_size)
key->data = gnutls_malloc(key->size);
if (!key->data) {
gnutls_assert();
- return GNUTLS_E_MEMORY_ERROR;
+ ret = GNUTLS_E_MEMORY_ERROR;
+ goto error;
+ }
+
+ /* Key lengths of less than 112 bits are not approved */
+ if (key_size < 14) {
+ not_approved = true;
}
ret = gnutls_rnd(GNUTLS_RND_RANDOM, key->data, key->size);
if (ret < 0) {
gnutls_assert();
_gnutls_free_datum(key);
- return ret;
+ goto error;
}
- return 0;
+ error:
+ if (ret < 0) {
+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
+ } else if (not_approved) {
+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_NOT_APPROVED);
+ } else {
+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_APPROVED);
+ }
+ return ret;
}
/* AEAD API */
@@ -2214,7 +2229,15 @@ gnutls_pbkdf2(gnutls_mac_algorithm_t mac,
if (!is_mac_algo_allowed(mac)) {
_gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
return gnutls_assert_val(GNUTLS_E_UNWANTED_ALGORITHM);
- } else if (!is_mac_algo_approved_in_fips(mac)) {
+ } else if (!is_mac_algo_hmac_approved_in_fips(mac)) {
+ /* ACVP only allows HMAC used with PBKDF2:
+ * https://pages.nist.gov/ACVP/draft-celi-acvp-pbkdf.html
+ */
+ not_approved = true;
+ }
+
+ /* Key lengths and output sizes of less than 112 bits are not approved */
+ if (key->size < 14 || length < 14) {
not_approved = true;
}
diff --git a/lib/fips.h b/lib/fips.h
index 3a74f254e7..bf61b36741 100644
--- a/lib/fips.h
+++ b/lib/fips.h
@@ -76,7 +76,7 @@ void _gnutls_lib_simulate_error(void);
void _gnutls_lib_force_operational(void);
inline static bool
-is_mac_algo_approved_in_fips(gnutls_mac_algorithm_t algo)
+is_mac_algo_hmac_approved_in_fips(gnutls_mac_algorithm_t algo)
{
switch (algo) {
case GNUTLS_MAC_SHA1:
@@ -88,6 +88,20 @@ is_mac_algo_approved_in_fips(gnutls_mac_algorithm_t algo)
case GNUTLS_MAC_SHA3_256:
case GNUTLS_MAC_SHA3_384:
case GNUTLS_MAC_SHA3_512:
+ return true;
+ default:
+ return false;
+ }
+}
+
+inline static bool
+is_mac_algo_approved_in_fips(gnutls_mac_algorithm_t algo)
+{
+ if (is_mac_algo_hmac_approved_in_fips(algo)) {
+ return true;
+ }
+
+ switch (algo) {
case GNUTLS_MAC_AES_CMAC_128:
case GNUTLS_MAC_AES_CMAC_256:
case GNUTLS_MAC_AES_GMAC_128:
diff --git a/tests/dh-compute.c b/tests/dh-compute.c
index 828fb05e9c..6c1d5328f6 100644
--- a/tests/dh-compute.c
+++ b/tests/dh-compute.c
@@ -156,34 +156,10 @@ void doit(void)
{ NULL }
};
-#define FIPS_PUSH_CONTEXT() do { \
- if (gnutls_fips140_mode_enabled()) { \
- ret = gnutls_fips140_push_context(fips_context); \
- if (ret < 0) { \
- fail("gnutls_fips140_push_context failed\n"); \
- } \
- } \
-} while (0)
-
-#define FIPS_POP_CONTEXT(state) do { \
- if (gnutls_fips140_mode_enabled()) { \
- ret = gnutls_fips140_pop_context(); \
- if (ret < 0) { \
- fail("gnutls_fips140_context_pop failed\n"); \
- } \
- fips_state = gnutls_fips140_get_operation_state(fips_context); \
- if (fips_state != state) { \
- fail("operation state is not %d (%d)\n", \
- state, fips_state); \
- } \
- } \
-} while (0)
-
for (int i = 0; test_data[i].name != NULL; i++) {
gnutls_datum_t priv_key, pub_key;
gnutls_dh_params_t dh_params;
gnutls_fips140_context_t fips_context;
- gnutls_fips140_operation_state_t fips_state;
int ret;
if (gnutls_fips140_mode_enabled()) {
@@ -193,24 +169,24 @@ void doit(void)
}
}
- FIPS_PUSH_CONTEXT();
+ fips_push_context(fips_context);
params(&dh_params, &test_data[i].prime, &test_data[i].q,
&test_data[i].generator);
- FIPS_POP_CONTEXT(GNUTLS_FIPS140_OP_INITIAL);
+ fips_pop_context(fips_context, GNUTLS_FIPS140_OP_INITIAL);
success("%s genkey\n", test_data[i].name);
- FIPS_PUSH_CONTEXT();
+ fips_push_context(fips_context);
genkey(dh_params, &priv_key, &pub_key);
- FIPS_POP_CONTEXT(test_data[i].fips_state_genkey);
+ fips_pop_context(fips_context, test_data[i].fips_state_genkey);
success("%s compute_key\n", test_data[i].name);
- FIPS_PUSH_CONTEXT();
+ fips_push_context(fips_context);
compute_key(test_data[i].name, dh_params, &priv_key,
&pub_key, &test_data[i].peer_key,
test_data[i].expected_error, NULL, 0);
- FIPS_POP_CONTEXT(test_data[i].fips_state_compute_key);
+ fips_pop_context(fips_context, test_data[i].fips_state_compute_key);
gnutls_dh_params_deinit(dh_params);
gnutls_free(priv_key.data);
diff --git a/tests/fips-rsa-sizes.c b/tests/fips-rsa-sizes.c
index 84b9affabb..5feb284503 100644
--- a/tests/fips-rsa-sizes.c
+++ b/tests/fips-rsa-sizes.c
@@ -27,25 +27,6 @@
#include <gnutls/abstract.h>
#include <gnutls/x509.h>
-#define FIPS_PUSH_CONTEXT() do { \
- ret = gnutls_fips140_push_context(fips_context); \
- if (ret < 0) { \
- fail("gnutls_fips140_push_context failed\n"); \
- } \
-} while (0)
-
-#define FIPS_POP_CONTEXT(state) do { \
- ret = gnutls_fips140_pop_context(); \
- if (ret < 0) { \
- fail("gnutls_fips140_context_pop failed\n"); \
- } \
- fips_state = gnutls_fips140_get_operation_state(fips_context); \
- if (fips_state != GNUTLS_FIPS140_OP_ ## state) { \
- fail("operation state is not " # state " (%d)\n", \
- fips_state); \
- } \
-} while (0)
-
void generate_successfully(gnutls_privkey_t* privkey, gnutls_pubkey_t* pubkey,
unsigned int size);
@@ -63,7 +44,6 @@ void generate_successfully(gnutls_privkey_t* privkey, gnutls_pubkey_t* pubkey,
int ret;
gnutls_x509_privkey_t xprivkey;
gnutls_fips140_context_t fips_context;
- gnutls_fips140_operation_state_t fips_state;
assert(gnutls_fips140_context_init(&fips_context) == 0);
fprintf(stderr, "%d-bit\n", size);
@@ -102,7 +82,6 @@ void generate_unsuccessfully(gnutls_privkey_t* privkey, gnutls_pubkey_t* pubkey,
int ret;
gnutls_x509_privkey_t xprivkey;
gnutls_fips140_context_t fips_context;
- gnutls_fips140_operation_state_t fips_state;
assert(gnutls_fips140_context_init(&fips_context) == 0);
fprintf(stderr, "%d-bit\n", size);
@@ -156,7 +135,6 @@ void generate_unsuccessfully(gnutls_privkey_t* privkey, gnutls_pubkey_t* pubkey,
void sign_verify_successfully(gnutls_privkey_t privkey, gnutls_pubkey_t pubkey) {
int ret;
gnutls_fips140_context_t fips_context;
- gnutls_fips140_operation_state_t fips_state;
gnutls_datum_t signature;
gnutls_datum_t plaintext = {
@@ -190,7 +168,6 @@ void sign_verify_unsuccessfully(gnutls_privkey_t privkey,
gnutls_pubkey_t pubkey) {
int ret;
gnutls_fips140_context_t fips_context;
- gnutls_fips140_operation_state_t fips_state;
gnutls_datum_t signature;
gnutls_datum_t plaintext = {
@@ -225,7 +202,6 @@ void sign_verify_unsuccessfully(gnutls_privkey_t privkey,
void nosign_verify(gnutls_privkey_t privkey, gnutls_pubkey_t pubkey) {
int ret;
gnutls_fips140_context_t fips_context;
- gnutls_fips140_operation_state_t fips_state;
gnutls_datum_t signature;
gnutls_datum_t plaintext = {
diff --git a/tests/fips-test.c b/tests/fips-test.c
index f789afb107..f7556d7bbb 100644
--- a/tests/fips-test.c
+++ b/tests/fips-test.c
@@ -12,25 +12,6 @@
/* This does check the FIPS140 support.
*/
-#define FIPS_PUSH_CONTEXT() do { \
- ret = gnutls_fips140_push_context(fips_context); \
- if (ret < 0) { \
- fail("gnutls_fips140_push_context failed\n"); \
- } \
-} while (0)
-
-#define FIPS_POP_CONTEXT(state) do { \
- ret = gnutls_fips140_pop_context(); \
- if (ret < 0) { \
- fail("gnutls_fips140_context_pop failed\n"); \
- } \
- fips_state = gnutls_fips140_get_operation_state(fips_context); \
- if (fips_state != GNUTLS_FIPS140_OP_ ## state) { \
- fail("operation state is not " # state " (%d)\n", \
- fips_state); \
- } \
-} while (0)
-
void _gnutls_lib_simulate_error(void);
static void tls_log_func(int level, const char *str)
@@ -40,10 +21,9 @@ static void tls_log_func(int level, const char *str)
static uint8_t key16[16];
static uint8_t iv16[16];
-uint8_t key_data[64];
-uint8_t iv_data[16];
-gnutls_fips140_context_t fips_context;
-gnutls_fips140_operation_state_t fips_state;
+static uint8_t key_data[64];
+static uint8_t iv_data[16];
+static gnutls_fips140_context_t fips_context;
static const gnutls_datum_t data = { .data = (unsigned char *)"foo", 3 };
static const uint8_t rsa2342_sha1_sig_data[] = {
@@ -276,6 +256,7 @@ test_ciphers(void)
void doit(void)
{
int ret;
+ gnutls_fips140_operation_state_t fips_state;
unsigned int mode;
gnutls_cipher_hd_t ch;
gnutls_hmac_hd_t mh;
@@ -290,6 +271,8 @@ void doit(void)
uint8_t hmac[64];
uint8_t hash[64];
gnutls_datum_t hashed_data;
+ uint8_t pbkdf2[64];
+ gnutls_datum_t temp_key = { NULL, 0 };
fprintf(stderr,
"Please note that if in FIPS140 mode, you need to assure the library's integrity prior to running this test\n");
@@ -387,11 +370,58 @@ void doit(void)
}
FIPS_POP_CONTEXT(NOT_APPROVED);
+ /* PBKDF2 with key equal to or longer than 112 bits: approved */
+ FIPS_PUSH_CONTEXT();
+ ret = gnutls_pbkdf2(GNUTLS_MAC_SHA256, &key, &iv, 100,
+ &pbkdf2, sizeof(pbkdf2));
+ if (ret < 0) {
+ fail("gnutls_pbkdf2 failed\n");
+ }
+ FIPS_POP_CONTEXT(APPROVED);
+
+ /* PBKDF2 with key shorter than 112 bits: not approved */
+ FIPS_PUSH_CONTEXT();
+ key.size = 13;
+ ret = gnutls_pbkdf2(GNUTLS_MAC_SHA256, &key, &iv, 100,
+ &pbkdf2, sizeof(pbkdf2));
+ if (ret < 0) {
+ fail("gnutls_pbkdf2 failed\n");
+ }
+ key.size = sizeof(key16);
+ FIPS_POP_CONTEXT(NOT_APPROVED);
+
+ /* PBKDF2 with output shorter than 112 bits: not approved */
+ FIPS_PUSH_CONTEXT();
+ ret = gnutls_pbkdf2(GNUTLS_MAC_SHA256, &key, &iv, 100,
+ &pbkdf2, 13);
+ if (ret < 0) {
+ fail("gnutls_pbkdf2 failed\n");
+ }
+ FIPS_POP_CONTEXT(NOT_APPROVED);
+
ret = gnutls_rnd(GNUTLS_RND_NONCE, key16, sizeof(key16));
if (ret < 0) {
fail("gnutls_rnd failed\n");
}
+ /* Symmetric key generation equal to or longer than 112 bits: approved */
+ FIPS_PUSH_CONTEXT();
+ ret = gnutls_key_generate(&temp_key, 14);
+ if (ret < 0) {
+ fail("gnutls_key_generate failed\n");
+ }
+ gnutls_free(temp_key.data);
+ FIPS_POP_CONTEXT(APPROVED);
+
+ /* Symmetric key generation shorter than 112 bits: not approved */
+ FIPS_PUSH_CONTEXT();
+ ret = gnutls_key_generate(&temp_key, 13);
+ if (ret < 0) {
+ fail("gnutls_key_generate failed\n");
+ }
+ gnutls_free(temp_key.data);
+ FIPS_POP_CONTEXT(NOT_APPROVED);
+
ret = gnutls_pubkey_init(&pubkey);
if (ret < 0) {
fail("gnutls_pubkey_init failed\n");
diff --git a/tests/kdf-api.c b/tests/kdf-api.c
index 9724502005..2e70d09ca1 100644
--- a/tests/kdf-api.c
+++ b/tests/kdf-api.c
@@ -26,6 +26,7 @@
#include <gnutls/crypto.h>
#include <assert.h>
+#include <stdbool.h>
#include <stdint.h>
#include "utils.h"
@@ -33,30 +34,7 @@
#define MAX_BUF 1024
static gnutls_fips140_context_t fips_context;
-static gnutls_fips140_operation_state_t fips_state;
-
-#define FIPS_PUSH_CONTEXT() do { \
- if (gnutls_fips140_mode_enabled()) { \
- ret = gnutls_fips140_push_context(fips_context); \
- if (ret < 0) { \
- fail("gnutls_fips140_push_context failed\n"); \
- } \
- } \
-} while (0)
-
-#define FIPS_POP_CONTEXT(state) do { \
- if (gnutls_fips140_mode_enabled()) { \
- ret = gnutls_fips140_pop_context(); \
- if (ret < 0) { \
- fail("gnutls_fips140_context_pop failed\n"); \
- } \
- fips_state = gnutls_fips140_get_operation_state(fips_context); \
- if (fips_state != GNUTLS_FIPS140_OP_ ## state) { \
- fail("operation state is not " # state " (%d)\n", \
- fips_state); \
- } \
- } \
-} while (0)
+
static void
test_hkdf(gnutls_mac_algorithm_t mac,
@@ -74,7 +52,6 @@ test_hkdf(gnutls_mac_algorithm_t mac,
gnutls_datum_t prk;
gnutls_datum_t okm;
uint8_t buf[MAX_BUF];
- int ret;
success("HKDF test with %s\n", gnutls_mac_get_name(mac));
@@ -89,6 +66,7 @@ test_hkdf(gnutls_mac_algorithm_t mac,
FIPS_PUSH_CONTEXT();
assert(gnutls_hkdf_extract(mac, &ikm, &salt, buf) >= 0);
+ /* HKDF outside of TLS usage is not approved */
FIPS_POP_CONTEXT(NOT_APPROVED);
gnutls_free(ikm.data);
gnutls_free(salt.data);
@@ -116,6 +94,7 @@ test_hkdf(gnutls_mac_algorithm_t mac,
FIPS_PUSH_CONTEXT();
assert(gnutls_hkdf_expand(mac, &prk, &info, buf, length) >= 0);
+ /* HKDF outside of TLS usage is not approved */
FIPS_POP_CONTEXT(NOT_APPROVED);
gnutls_free(info.data);
@@ -131,20 +110,39 @@ test_hkdf(gnutls_mac_algorithm_t mac,
gnutls_free(hex.data);
}
+inline static bool
+is_mac_algo_hmac_approved_in_fips(gnutls_mac_algorithm_t algo)
+{
+ switch (algo) {
+ case GNUTLS_MAC_SHA1:
+ case GNUTLS_MAC_SHA256:
+ case GNUTLS_MAC_SHA384:
+ case GNUTLS_MAC_SHA512:
+ case GNUTLS_MAC_SHA224:
+ case GNUTLS_MAC_SHA3_224:
+ case GNUTLS_MAC_SHA3_256:
+ case GNUTLS_MAC_SHA3_384:
+ case GNUTLS_MAC_SHA3_512:
+ return true;
+ default:
+ return false;
+ }
+}
+
static void
test_pbkdf2(gnutls_mac_algorithm_t mac,
const char *ikm_hex,
const char *salt_hex,
unsigned iter_count,
size_t length,
- const char *okm_hex)
+ const char *okm_hex,
+ gnutls_fips140_operation_state_t expected_state)
{
gnutls_datum_t hex;
gnutls_datum_t ikm;
gnutls_datum_t salt;
gnutls_datum_t okm;
uint8_t buf[MAX_BUF];
- int ret;
success("PBKDF2 test with %s\n", gnutls_mac_get_name(mac));
@@ -156,9 +154,9 @@ test_pbkdf2(gnutls_mac_algorithm_t mac,
hex.size = strlen(salt_hex);
assert(gnutls_hex_decode2(&hex, &salt) >= 0);
- FIPS_PUSH_CONTEXT();
+ fips_push_context(fips_context);
assert(gnutls_pbkdf2(mac, &ikm, &salt, iter_count, buf, length) >= 0);
- FIPS_POP_CONTEXT(APPROVED);
+ fips_pop_context(fips_context, expected_state);
gnutls_free(ikm.data);
gnutls_free(salt.data);
@@ -199,7 +197,18 @@ doit(void)
"73616c74", /* "salt" */
4096,
20,
- "4b007901b765489abead49d926f721d065a429c1");
+ "4b007901b765489abead49d926f721d065a429c1",
+ /* Key sizes and output sizes less than 112-bit are not approved. */
+ GNUTLS_FIPS140_OP_NOT_APPROVED);
+
+ test_pbkdf2(GNUTLS_MAC_AES_CMAC_128,
+ "70617373776f726470617373776f7264", /* "passwordpassword" */
+ "73616c74", /* "salt" */
+ 4096,
+ 20,
+ "c4c112c6e1e3b8757640603dec78825ff87605a7",
+ /* Use of AES-CMAC in PBKDF2 is not supported in ACVP. */
+ GNUTLS_FIPS140_OP_NOT_APPROVED);
gnutls_fips140_context_deinit(fips_context);
}
diff --git a/tests/pkcs12_encode.c b/tests/pkcs12_encode.c
index ea39f3d69e..dc55daccde 100644
--- a/tests/pkcs12_encode.c
+++ b/tests/pkcs12_encode.c
@@ -70,29 +70,6 @@ static void tls_log_func(int level, const char *str)
fprintf(stderr, "|<%d>| %s", level, str);
}
-#define FIPS_PUSH_CONTEXT() do { \
- if (gnutls_fips140_mode_enabled()) { \
- ret = gnutls_fips140_push_context(fips_context); \
- if (ret < 0) { \
- fail("gnutls_fips140_push_context failed\n"); \
- } \
- } \
-} while (0)
-
-#define FIPS_POP_CONTEXT(state) do { \
- if (gnutls_fips140_mode_enabled()) { \
- ret = gnutls_fips140_pop_context(); \
- if (ret < 0) { \
- fail("gnutls_fips140_context_pop failed\n"); \
- } \
- fips_state = gnutls_fips140_get_operation_state(fips_context); \
- if (fips_state != GNUTLS_FIPS140_OP_ ## state) { \
- fail("operation state is not " # state " (%d)\n", \
- fips_state); \
- } \
- } \
-} while (0)
-
void doit(void)
{
gnutls_pkcs12_t pkcs12;
@@ -106,7 +83,6 @@ void doit(void)
size_t size;
unsigned i;
gnutls_fips140_context_t fips_context;
- gnutls_fips140_operation_state_t fips_state;
size_t n_tests = 0;
struct tests {
const char *name;
diff --git a/tests/privkey-keygen.c b/tests/privkey-keygen.c
index 2766afee08..2531906d71 100644
--- a/tests/privkey-keygen.c
+++ b/tests/privkey-keygen.c
@@ -119,30 +119,6 @@ void doit(void)
gnutls_x509_privkey_t pkey, dst;
int ret, algorithm, i;
gnutls_fips140_context_t fips_context;
- gnutls_fips140_operation_state_t fips_state;
-
-#define FIPS_PUSH_CONTEXT() do { \
- if (gnutls_fips140_mode_enabled()) { \
- ret = gnutls_fips140_push_context(fips_context); \
- if (ret < 0) { \
- fail("gnutls_fips140_push_context failed\n"); \
- } \
- } \
-} while (0)
-
-#define FIPS_POP_CONTEXT(state) do { \
- if (gnutls_fips140_mode_enabled()) { \
- ret = gnutls_fips140_pop_context(); \
- if (ret < 0) { \
- fail("gnutls_fips140_context_pop failed\n"); \
- } \
- fips_state = gnutls_fips140_get_operation_state(fips_context); \
- if (fips_state != GNUTLS_FIPS140_OP_ ## state) { \
- fail("operation state is not " # state " (%d)\n", \
- fips_state); \
- } \
- } \
-} while (0)
ret = global_init();
if (ret < 0)
diff --git a/tests/utils.h b/tests/utils.h
index d3a2ba8d16..4433a07057 100644
--- a/tests/utils.h
+++ b/tests/utils.h
@@ -210,4 +210,62 @@ inline static unsigned int get_dtls_retransmit_timeout(void) {
return (unsigned int) ul;
}
+static inline const char *
+fips_operation_state_to_string(gnutls_fips140_operation_state_t state)
+{
+ switch (state) {
+ case GNUTLS_FIPS140_OP_INITIAL:
+ return "INITIAL";
+ case GNUTLS_FIPS140_OP_APPROVED:
+ return "APPROVED";
+ case GNUTLS_FIPS140_OP_NOT_APPROVED:
+ return "NOT_APPROVED";
+ case GNUTLS_FIPS140_OP_ERROR:
+ return "ERROR";
+ default:
+ /*NOTREACHED*/
+ assert(0);
+ return NULL;
+ }
+}
+
+static inline void
+fips_push_context(gnutls_fips140_context_t context)
+{
+ if (gnutls_fips140_mode_enabled()) {
+ int ret;
+
+ ret = gnutls_fips140_push_context(context);
+ if (ret < 0) {
+ fail("gnutls_fips140_push_context failed\n");
+ }
+ }
+}
+
+static inline void
+fips_pop_context(gnutls_fips140_context_t context,
+ gnutls_fips140_operation_state_t expected_state)
+{
+ gnutls_fips140_operation_state_t state;
+
+ if (gnutls_fips140_mode_enabled()) {
+ int ret;
+
+ ret = gnutls_fips140_pop_context();
+ if (ret < 0) {
+ fail("gnutls_fips140_context_pop failed\n");
+ }
+ state = gnutls_fips140_get_operation_state(context);
+ if (state != expected_state) {
+ fail("operation state is not %s (%s)\n",
+ fips_operation_state_to_string(expected_state),
+ fips_operation_state_to_string(state));
+ }
+ }
+}
+
+/* To use those convenient macros, define fips_context variable. */
+#define FIPS_PUSH_CONTEXT() fips_push_context(fips_context)
+#define FIPS_POP_CONTEXT(state) fips_pop_context(fips_context, GNUTLS_FIPS140_OP_ ## state)
+
#endif /* GNUTLS_TESTS_UTILS_H */