1 #include <config.h>
2 #include <stdint.h>
3 #include <stdio.h>
4 #include <string.h>
5 #include <utils.h>
6 #include <stdlib.h>
7 #include <gnutls/gnutls.h>
8 #include <gnutls/crypto.h>
9 #include <gnutls/abstract.h>
10 #include <gnutls/x509.h>
11 #include <assert.h>
12 
13 unsigned audit_called = 0;
14 
15 /* This does check the FIPS140 override support with
16  * gnutls_fips140_set_mode().
17  */
18 
tls_log_func(int level,const char * str)19 static void tls_log_func(int level, const char *str)
20 {
21 	fprintf(stderr, "<%d>| %s", level, str);
22 }
23 
audit_log_func(gnutls_session_t session,const char * str)24 static void audit_log_func(gnutls_session_t session, const char *str)
25 {
26 	audit_called = 1;
27 }
28 
29 
try_crypto(void)30 static void try_crypto(void)
31 {
32 	static uint8_t key16[16];
33 	static uint8_t iv16[16];
34 	gnutls_datum_t key = { key16, sizeof(key16) };
35 	gnutls_datum_t iv = { iv16, sizeof(iv16) };
36 	gnutls_cipher_hd_t ch;
37 	gnutls_hmac_hd_t mh;
38 	int ret;
39 	gnutls_x509_privkey_t privkey;
40 
41 	ret =
42 	    gnutls_cipher_init(&ch, GNUTLS_CIPHER_ARCFOUR_128, &key, &iv);
43 	if (ret < 0) {
44 		fail("gnutls_cipher_init failed\n");
45 	}
46 	gnutls_cipher_deinit(ch);
47 
48 	ret =
49 	    gnutls_cipher_init(&ch, GNUTLS_CIPHER_AES_128_CBC, &key, &iv);
50 	if (ret < 0) {
51 		fail("gnutls_cipher_init failed\n");
52 	}
53 	gnutls_cipher_deinit(ch);
54 
55 	ret = gnutls_hmac_init(&mh, GNUTLS_MAC_MD5, key.data, key.size);
56 	if (ret < 0) {
57 		fail("gnutls_hmac_init failed\n");
58 	}
59 	gnutls_hmac_deinit(mh, NULL);
60 
61 	ret = gnutls_hmac_init(&mh, GNUTLS_MAC_SHA1, key.data, key.size);
62 	if (ret < 0) {
63 		fail("gnutls_hmac_init failed\n");
64 	}
65 	gnutls_hmac_deinit(mh, NULL);
66 
67 	ret = gnutls_rnd(GNUTLS_RND_NONCE, key16, sizeof(key16));
68 	if (ret < 0) {
69 		fail("gnutls_rnd failed\n");
70 	}
71 
72 	assert(gnutls_x509_privkey_init(&privkey) == 0);
73 	ret = gnutls_x509_privkey_generate(privkey, GNUTLS_PK_RSA, 512, 0);
74 	if (ret < 0) {
75 		fail("gnutls_x509_privkey_generate failed for 512-bit key\n");
76 	}
77 	gnutls_x509_privkey_deinit(privkey);
78 }
79 
doit(void)80 void doit(void)
81 {
82 	int ret;
83 	unsigned int mode;
84 
85 	fprintf(stderr,
86 		"Please note that if in FIPS140 mode, you need to assure the library's integrity prior to running this test\n");
87 
88 	gnutls_global_set_log_function(tls_log_func);
89 	gnutls_global_set_audit_log_function(audit_log_func);
90 	if (debug)
91 		gnutls_global_set_log_level(4711);
92 
93 	mode = gnutls_fips140_mode_enabled();
94 	if (mode == 0) {
95 		success("We are not in FIPS140 mode\n");
96 		exit(77);
97 	}
98 
99 	ret = global_init();
100 	if (ret < 0) {
101 		fail("Cannot initialize library\n");
102 	}
103 
104 	/* switch to lax mode and check whether forbidden algorithms are accessible */
105 	gnutls_fips140_set_mode(GNUTLS_FIPS140_LAX, 0);
106 
107 	try_crypto();
108 
109 	/* check whether audit log was called */
110 	if (audit_called) {
111 		fail("the audit function was called in lax mode!\n");
112 	}
113 
114 	gnutls_fips140_set_mode(GNUTLS_FIPS140_LOG, 0);
115 
116 	try_crypto();
117 
118 	/* check whether audit log was called */
119 	if (!audit_called) {
120 		fail("the audit function was not called in log mode!\n");
121 	}
122 
123 	gnutls_fips140_set_mode(GNUTLS_FIPS140_SELFTESTS, 0);
124 	if (gnutls_fips140_mode_enabled() != GNUTLS_FIPS140_STRICT)
125 		fail("switching to selftests didn't switch the lib to the expected mode\n");
126 
127 	gnutls_fips140_set_mode(532, 0);
128 	if (gnutls_fips140_mode_enabled() != GNUTLS_FIPS140_STRICT)
129 		fail("switching to unknown mode didn't switch the lib to the expected mode\n");
130 
131 	GNUTLS_FIPS140_SET_LAX_MODE();
132 	if (gnutls_fips140_mode_enabled() != GNUTLS_FIPS140_LAX)
133 		fail("switching to lax mode did not succeed!\n");
134 
135 	GNUTLS_FIPS140_SET_STRICT_MODE();
136 	if (gnutls_fips140_mode_enabled() != GNUTLS_FIPS140_STRICT)
137 		fail("switching to strict mode did not succeed!\n");
138 
139 	gnutls_global_deinit();
140 	return;
141 }
142