2 * digest support for NTP, MD5 and with OpenSSL more
9 #include "ntp_string.h"
10 #include "ntp_stdlib.h"
12 #include "ntp_md5.h" /* provides OpenSSL digest API */
13 #include "isc/string.h"
14 #include "libssl_compat.h"
16 * MD5authencrypt - generate message digest
18 * Returns length of MAC including key ID and digest.
22 int type, /* hash algorithm */
23 const u_char * key, /* key pointer */
24 u_int32 * pkt, /* packet pointer */
25 size_t length /* packet length */
28 u_char digest[EVP_MAX_MD_SIZE];
33 * Compute digest of key concatenated with packet. Note: the
34 * key type and digest type have been verified when the key
38 ctx = EVP_MD_CTX_new();
39 if (!(ctx && EVP_DigestInit(ctx, EVP_get_digestbynid(type)))) {
41 "MAC encrypt: digest init failed");
45 EVP_DigestUpdate(ctx, key, cache_secretsize);
46 EVP_DigestUpdate(ctx, (u_char *)pkt, length);
47 EVP_DigestFinal(ctx, digest, &len);
49 /* If the MAC is longer than the MAX then truncate it. */
50 if (len > MAX_MAC_LEN - 4)
51 len = MAX_MAC_LEN - 4;
52 memmove((u_char *)pkt + length + 4, digest, len);
58 * MD5authdecrypt - verify MD5 message authenticator
60 * Returns one if digest valid, zero if invalid.
64 int type, /* hash algorithm */
65 const u_char * key, /* key pointer */
66 u_int32 * pkt, /* packet pointer */
67 size_t length, /* packet length */
68 size_t size /* MAC size */
71 u_char digest[EVP_MAX_MD_SIZE];
76 * Compute digest of key concatenated with packet. Note: the
77 * key type and digest type have been verified when the key
81 ctx = EVP_MD_CTX_new();
82 if (!(ctx && EVP_DigestInit(ctx, EVP_get_digestbynid(type)))) {
84 "MAC decrypt: digest init failed");
88 EVP_DigestUpdate(ctx, key, cache_secretsize);
89 EVP_DigestUpdate(ctx, (u_char *)pkt, length);
90 EVP_DigestFinal(ctx, digest, &len);
92 /* If the MAC is longer than the MAX then truncate it. */
93 if (len > MAX_MAC_LEN - 4)
94 len = MAX_MAC_LEN - 4;
95 if (size != (size_t)len + 4) {
97 "MAC decrypt: MAC length error");
100 return !isc_tsmemcmp(digest, (u_char *)pkt + length + 4, len);
104 * Calculate the reference id from the address. If it is an IPv4
105 * address, use it as is. If it is an IPv6 address, do a md5 on
106 * it and use the bottom 4 bytes.
107 * The result is in network byte order.
110 addr2refid(sockaddr_u *addr)
118 return (NSRCADR(addr));
122 ctx = EVP_MD_CTX_new();
123 EVP_MD_CTX_init(ctx);
124 #ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW
125 /* MD5 is not used as a crypto hash here. */
126 EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
128 if (!EVP_DigestInit_ex(ctx, EVP_md5(), NULL)) {
131 EVP_MD_CTX_free(ctx); /* pedantic... but safe */
135 EVP_DigestUpdate(ctx, (u_char *)PSOCK_ADDR6(addr),
136 sizeof(struct in6_addr));
137 EVP_DigestFinal(ctx, digest, &len);
138 EVP_MD_CTX_free(ctx);
139 memcpy(&addr_refid, digest, sizeof(addr_refid));