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 ctx = EVP_MD_CTX_new();
38 if (!(ctx && EVP_DigestInit(ctx, EVP_get_digestbynid(type)))) {
40 "MAC encrypt: digest init failed");
44 EVP_DigestUpdate(ctx, key, cache_secretsize);
45 EVP_DigestUpdate(ctx, (u_char *)pkt, length);
46 EVP_DigestFinal(ctx, digest, &len);
48 /* If the MAC is longer than the MAX then truncate it. */
49 if (len > MAX_MAC_LEN - 4)
50 len = MAX_MAC_LEN - 4;
51 memmove((u_char *)pkt + length + 4, digest, len);
57 * MD5authdecrypt - verify MD5 message authenticator
59 * Returns one if digest valid, zero if invalid.
63 int type, /* hash algorithm */
64 const u_char * key, /* key pointer */
65 u_int32 * pkt, /* packet pointer */
66 size_t length, /* packet length */
67 size_t size /* MAC size */
70 u_char digest[EVP_MAX_MD_SIZE];
75 * Compute digest of key concatenated with packet. Note: the
76 * key type and digest type have been verified when the key
80 ctx = EVP_MD_CTX_new();
81 if (!(ctx && EVP_DigestInit(ctx, EVP_get_digestbynid(type)))) {
83 "MAC decrypt: digest init failed");
87 EVP_DigestUpdate(ctx, key, cache_secretsize);
88 EVP_DigestUpdate(ctx, (u_char *)pkt, length);
89 EVP_DigestFinal(ctx, digest, &len);
91 /* If the MAC is longer than the MAX then truncate it. */
92 if (len > MAX_MAC_LEN - 4)
93 len = MAX_MAC_LEN - 4;
94 if (size != (size_t)len + 4) {
96 "MAC decrypt: MAC length error");
99 return !isc_tsmemcmp(digest, (u_char *)pkt + length + 4, len);
103 * Calculate the reference id from the address. If it is an IPv4
104 * address, use it as is. If it is an IPv6 address, do a md5 on
105 * it and use the bottom 4 bytes.
106 * The result is in network byte order.
109 addr2refid(sockaddr_u *addr)
117 return (NSRCADR(addr));
121 ctx = EVP_MD_CTX_new();
122 EVP_MD_CTX_init(ctx);
123 #ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW
124 /* MD5 is not used as a crypto hash here. */
125 EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
127 if (!EVP_DigestInit_ex(ctx, EVP_md5(), NULL)) {
130 EVP_MD_CTX_free(ctx); /* pedantic... but safe */
134 EVP_DigestUpdate(ctx, (u_char *)PSOCK_ADDR6(addr),
135 sizeof(struct in6_addr));
136 EVP_DigestFinal(ctx, digest, &len);
137 EVP_MD_CTX_free(ctx);
138 memcpy(&addr_refid, digest, sizeof(addr_refid));