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"
15 * MD5authencrypt - generate message digest
17 * Returns length of MAC including key ID and digest.
21 int type, /* hash algorithm */
22 const u_char * key, /* key pointer */
23 u_int32 * pkt, /* packet pointer */
24 size_t length /* packet length */
27 u_char digest[EVP_MAX_MD_SIZE];
32 * Compute digest of key concatenated with packet. Note: the
33 * key type and digest type have been verified when the key
37 #if defined(OPENSSL) && OPENSSL_VERSION_NUMBER >= 0x0090700fL
38 if (!EVP_DigestInit(&ctx, EVP_get_digestbynid(type))) {
40 "MAC encrypt: digest init failed");
44 EVP_DigestInit(&ctx, EVP_get_digestbynid(type));
46 EVP_DigestUpdate(&ctx, key, cache_secretsize);
47 EVP_DigestUpdate(&ctx, (u_char *)pkt, length);
48 EVP_DigestFinal(&ctx, digest, &len);
49 memmove((u_char *)pkt + length + 4, digest, len);
55 * MD5authdecrypt - verify MD5 message authenticator
57 * Returns one if digest valid, zero if invalid.
61 int type, /* hash algorithm */
62 const u_char * key, /* key pointer */
63 u_int32 * pkt, /* packet pointer */
64 size_t length, /* packet length */
65 size_t size /* MAC size */
68 u_char digest[EVP_MAX_MD_SIZE];
73 * Compute digest of key concatenated with packet. Note: the
74 * key type and digest type have been verified when the key
78 #if defined(OPENSSL) && OPENSSL_VERSION_NUMBER >= 0x0090700fL
79 if (!EVP_DigestInit(&ctx, EVP_get_digestbynid(type))) {
81 "MAC decrypt: digest init failed");
85 EVP_DigestInit(&ctx, EVP_get_digestbynid(type));
87 EVP_DigestUpdate(&ctx, key, cache_secretsize);
88 EVP_DigestUpdate(&ctx, (u_char *)pkt, length);
89 EVP_DigestFinal(&ctx, digest, &len);
90 if (size != (size_t)len + 4) {
92 "MAC decrypt: MAC length error");
95 return !isc_tsmemcmp(digest, (const char *)pkt + length + 4, len);
99 * Calculate the reference id from the address. If it is an IPv4
100 * address, use it as is. If it is an IPv6 address, do a md5 on
101 * it and use the bottom 4 bytes.
102 * The result is in network byte order.
105 addr2refid(sockaddr_u *addr)
113 return (NSRCADR(addr));
117 #if defined(OPENSSL) && OPENSSL_VERSION_NUMBER >= 0x0090700fL
118 EVP_MD_CTX_init(&ctx);
119 #ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW
120 /* MD5 is not used as a crypto hash here. */
121 EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
123 if (!EVP_DigestInit_ex(&ctx, EVP_md5(), NULL)) {
129 EVP_DigestInit(&ctx, EVP_md5());
132 EVP_DigestUpdate(&ctx, (u_char *)PSOCK_ADDR6(addr),
133 sizeof(struct in6_addr));
134 EVP_DigestFinal(&ctx, digest, &len);
135 memcpy(&addr_refid, digest, sizeof(addr_refid));