d97e51c1cd184ba8aaf4814d7a81a049e68e290a
[strongswan.git] / src / libstrongswan / fips / fips.c
1 /**
2 * @file fips.c
3 *
4 * @brief Implementation of the libstrongswan integrity test.
5 *
6 */
7
8 /*
9 * Copyright (C) 2007 Bruno Krieg, Daniel Wydler
10 * Hochschule fuer Technik Rapperswil
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * for more details.
21 */
22
23 #include "fips.h"
24 #include <debug.h>
25 #include <crypto/signers/hmac_signer.h>
26
27 extern const u_char FIPS_rodata_start[];
28 extern const u_char FIPS_rodata_end[];
29 extern const void *FIPS_text_start();
30 extern const void *FIPS_text_end();
31
32 /**
33 * Described in header
34 */
35 bool fips_compute_hmac_signature(const char *key, char *signature)
36 {
37 u_char *text_start = (u_char *)FIPS_text_start();
38 u_char *text_end = (u_char *)FIPS_text_end();
39 size_t text_len;
40 size_t rodata_len;
41 signer_t *signer;
42
43 if (text_start > text_end)
44 {
45 DBG1(" TEXT start (%p) > TEXT end (%p",
46 text_start, text_end);
47 return FALSE;
48 }
49 text_len = (size_t)text_end - (size_t)text_start;
50 DBG1(" TEXT: %p + %6d = %p",
51 text_start, (int)text_len, text_end);
52
53 if (FIPS_rodata_start > FIPS_rodata_end)
54 {
55 DBG1(" RODATA start (%p) > RODATA end (%p",
56 FIPS_rodata_start, FIPS_rodata_end);
57 return FALSE;
58 }
59 rodata_len = (size_t)FIPS_rodata_end - (size_t)FIPS_rodata_start;
60 DBG1(" RODATA: %p + %6d = %p",
61 FIPS_rodata_start, (int)rodata_len, FIPS_rodata_end);
62
63 signer = (signer_t *)hmac_signer_create(HASH_SHA1, HASH_SIZE_SHA1);
64 if (signer == NULL)
65 {
66 DBG1(" SHA-1 HMAC signer could not be created");
67 return FALSE;
68 }
69 else
70 {
71 chunk_t hmac_key = { key, strlen(key) };
72 chunk_t text_chunk = { text_start, text_len };
73 chunk_t rodata_chunk = { (u_char *)FIPS_rodata_start, rodata_len };
74 chunk_t signature_chunk = chunk_empty;
75
76 signer->set_key(signer, hmac_key);
77 /* TODO include rodata_chunk in HMAC */
78 signer->allocate_signature(signer, text_chunk, &signature_chunk);
79 signer->destroy(signer);
80
81 sprintf(signature, "%#B", &signature_chunk);
82 DBG1(" SHA-1 HMAC key: %s", key);
83 DBG1(" SHA-1 HMAC sig: %s", signature);
84 free(signature_chunk.ptr);
85 return TRUE;
86 }
87 }
88
89 /**
90 * Described in header
91 */
92 bool fips_verify_hmac_signature(const char *key,
93 const char *signature)
94 {
95 char current_signature[BUF_LEN];
96
97 if (!fips_compute_hmac_signature(key, current_signature))
98 {
99 return FALSE;
100 }
101 return streq(signature, current_signature);
102 }