1 /* $NetBSD: crypto.c,v 1.10 2016/05/01 23:32:01 christos Exp $ */ 2 3 #include <config.h> 4 #include "crypto.h" 5 #include <ctype.h> 6 #include "isc/string.h" 7 8 struct key *key_ptr; 9 size_t key_cnt = 0; 10 11 int 12 make_mac( 13 const void *pkt_data, 14 int pkt_size, 15 int mac_size, 16 const struct key *cmp_key, 17 void * digest 18 ) 19 { 20 u_int len = mac_size; 21 int key_type; 22 EVP_MD_CTX ctx; 23 24 if (cmp_key->key_len > 64) 25 return 0; 26 if (pkt_size % 4 != 0) 27 return 0; 28 29 INIT_SSL(); 30 key_type = keytype_from_text(cmp_key->type, NULL); 31 EVP_DigestInit(&ctx, EVP_get_digestbynid(key_type)); 32 EVP_DigestUpdate(&ctx, (const u_char *)cmp_key->key_seq, (u_int)cmp_key->key_len); 33 EVP_DigestUpdate(&ctx, pkt_data, (u_int)pkt_size); 34 EVP_DigestFinal(&ctx, digest, &len); 35 36 return (int)len; 37 } 38 39 40 /* Generates a md5 digest of the key specified in keyid concatenated with the 41 * ntp packet (exluding the MAC) and compares this digest to the digest in 42 * the packet's MAC. If they're equal this function returns 1 (packet is 43 * authentic) or else 0 (not authentic). 44 */ 45 int 46 auth_md5( 47 const void *pkt_data, 48 int pkt_size, 49 int mac_size, 50 const struct key *cmp_key 51 ) 52 { 53 int hash_len; 54 int authentic; 55 char digest[20]; 56 const u_char *pkt_ptr; 57 if (mac_size > (int)sizeof(digest)) 58 return 0; 59 pkt_ptr = pkt_data; 60 hash_len = make_mac(pkt_ptr, pkt_size, sizeof(digest), cmp_key, 61 digest); 62 if (!hash_len) { 63 authentic = FALSE; 64 } else { 65 /* isc_tsmemcmp will be better when its easy to link 66 * with. sntp is a 1-shot program, so snooping for 67 * timing attacks is Harder. 68 */ 69 authentic = !memcmp(digest, pkt_ptr + pkt_size + 4, 70 hash_len); 71 } 72 return authentic; 73 } 74 75 static int 76 hex_val( 77 unsigned char x 78 ) 79 { 80 int val; 81 82 if ('0' <= x && x <= '9') 83 val = x - '0'; 84 else if ('a' <= x && x <= 'f') 85 val = x - 'a' + 0xa; 86 else if ('A' <= x && x <= 'F') 87 val = x - 'A' + 0xA; 88 else 89 val = -1; 90 91 return val; 92 } 93 94 /* Load keys from the specified keyfile into the key structures. 95 * Returns -1 if the reading failed, otherwise it returns the 96 * number of keys it read 97 */ 98 int 99 auth_init( 100 const char *keyfile, 101 struct key **keys 102 ) 103 { 104 FILE *keyf = fopen(keyfile, "r"); 105 struct key *prev = NULL; 106 int scan_cnt, line_cnt = 0; 107 char kbuf[200]; 108 char keystring[129]; 109 110 if (keyf == NULL) { 111 if (debug) 112 printf("sntp auth_init: Couldn't open key file %s for reading!\n", keyfile); 113 return -1; 114 } 115 if (feof(keyf)) { 116 if (debug) 117 printf("sntp auth_init: Key file %s is empty!\n", keyfile); 118 fclose(keyf); 119 return -1; 120 } 121 key_cnt = 0; 122 while (!feof(keyf)) { 123 char * octothorpe; 124 struct key *act; 125 int goodline = 0; 126 127 if (NULL == fgets(kbuf, sizeof(kbuf), keyf)) 128 continue; 129 130 kbuf[sizeof(kbuf) - 1] = '\0'; 131 octothorpe = strchr(kbuf, '#'); 132 if (octothorpe) 133 *octothorpe = '\0'; 134 act = emalloc(sizeof(*act)); 135 scan_cnt = sscanf(kbuf, "%d %9s %128s", &act->key_id, act->type, keystring); 136 if (scan_cnt == 3) { 137 int len = strlen(keystring); 138 if (len <= 20) { 139 act->key_len = len; 140 memcpy(act->key_seq, keystring, len + 1); 141 goodline = 1; 142 } else if ((len & 1) != 0) { 143 goodline = 0; /* it's bad */ 144 } else { 145 int j; 146 goodline = 1; 147 act->key_len = len >> 1; 148 for (j = 0; j < len; j+=2) { 149 int val; 150 val = (hex_val(keystring[j]) << 4) | 151 hex_val(keystring[j+1]); 152 if (val < 0) { 153 goodline = 0; /* it's bad */ 154 break; 155 } 156 act->key_seq[j>>1] = (char)val; 157 } 158 } 159 } 160 if (goodline) { 161 act->next = NULL; 162 if (NULL == prev) 163 *keys = act; 164 else 165 prev->next = act; 166 prev = act; 167 key_cnt++; 168 } else { 169 msyslog(LOG_DEBUG, "auth_init: scanf %d items, skipping line %d.", 170 scan_cnt, line_cnt); 171 free(act); 172 } 173 line_cnt++; 174 } 175 fclose(keyf); 176 177 key_ptr = *keys; 178 return key_cnt; 179 } 180 181 /* Looks for the key with keyid key_id and sets the d_key pointer to the 182 * address of the key. If no matching key is found the pointer is not touched. 183 */ 184 void 185 get_key( 186 int key_id, 187 struct key **d_key 188 ) 189 { 190 struct key *itr_key; 191 192 if (key_cnt == 0) 193 return; 194 for (itr_key = key_ptr; itr_key; itr_key = itr_key->next) { 195 if (itr_key->key_id == key_id) { 196 *d_key = itr_key; 197 break; 198 } 199 } 200 return; 201 } 202