1 /* 2 * authkeys.c - routines to manage the storage of authentication keys 3 */ 4 5 #ifdef HAVE_CONFIG_H 6 # include <config.h> 7 #endif 8 9 #include <stdio.h> 10 11 #include "ntp_types.h" 12 #include "ntp_fp.h" 13 #include "ntp.h" 14 #include "ntpd.h" 15 #include "ntp_string.h" 16 #include "ntp_malloc.h" 17 #include "ntp_stdlib.h" 18 19 /* 20 * Structure to store keys in in the hash table. 21 */ 22 struct savekey { 23 struct savekey *next; 24 union { 25 long bogon; /* Make sure nonempty */ 26 #ifdef DES 27 u_int32 DES_key[2]; /* DES key */ 28 #endif 29 u_char MD5_key[32]; /* MD5 key */ 30 } k; 31 keyid_t keyid; /* key identifier */ 32 u_short flags; /* flags that wave */ 33 u_long lifetime; /* remaining lifetime */ 34 int keylen; /* key length */ 35 }; 36 37 #define KEY_TRUSTED 0x001 /* this key is trusted */ 38 #define KEY_DES 0x100 /* this is a DES type key */ 39 #define KEY_MD5 0x200 /* this is a MD5 type key */ 40 41 /* 42 * The hash table. This is indexed by the low order bits of the 43 * keyid. We make this fairly big for potentially busy servers. 44 */ 45 #define HASHSIZE 64 46 #define HASHMASK ((HASHSIZE)-1) 47 #define KEYHASH(keyid) ((keyid) & HASHMASK) 48 49 struct savekey *key_hash[HASHSIZE]; 50 51 u_long authkeynotfound; /* keys not found */ 52 u_long authkeylookups; /* calls to lookup keys */ 53 u_long authnumkeys; /* number of active keys */ 54 u_long authkeyexpired; /* key lifetime expirations */ 55 u_long authkeyuncached; /* cache misses */ 56 u_long authnokey; /* calls to encrypt with no key */ 57 u_long authencryptions; /* calls to encrypt */ 58 u_long authdecryptions; /* calls to decrypt */ 59 60 /* 61 * Storage for free key structures. We malloc() such things but 62 * never free them. 63 */ 64 struct savekey *authfreekeys; 65 int authnumfreekeys; 66 67 #define MEMINC 12 /* number of new free ones to get */ 68 69 /* 70 * The key cache. We cache the last key we looked at here. 71 */ 72 keyid_t cache_keyid; /* key identifier */ 73 u_char *cache_key; /* key pointer */ 74 u_int cache_keylen; /* key length */ 75 u_short cache_flags; /* flags that wave */ 76 77 78 /* 79 * init_auth - initialize internal data 80 */ 81 void 82 init_auth(void) 83 { 84 /* 85 * Initialize hash table and free list 86 */ 87 memset((char *)key_hash, 0, sizeof key_hash); 88 } 89 90 91 /* 92 * auth_findkey - find a key in the hash table 93 */ 94 struct savekey * 95 auth_findkey( 96 keyid_t keyno 97 ) 98 { 99 struct savekey *sk; 100 101 sk = key_hash[KEYHASH(keyno)]; 102 while (sk != 0) { 103 if (keyno == sk->keyid) 104 return (sk); 105 106 sk = sk->next; 107 } 108 return (0); 109 } 110 111 112 /* 113 * auth_havekey - return one if the key is known 114 */ 115 int 116 auth_havekey( 117 keyid_t keyno 118 ) 119 { 120 struct savekey *sk; 121 122 if (keyno == 0 || (keyno == cache_keyid)) 123 return (1); 124 125 sk = key_hash[KEYHASH(keyno)]; 126 while (sk != 0) { 127 if (keyno == sk->keyid) 128 return (1); 129 130 sk = sk->next; 131 } 132 return (0); 133 } 134 135 136 /* 137 * authhavekey - return one and cache the key, if known and trusted. 138 */ 139 int 140 authhavekey( 141 keyid_t keyno 142 ) 143 { 144 struct savekey *sk; 145 146 authkeylookups++; 147 if (keyno == 0 || keyno == cache_keyid) 148 return (1); 149 150 authkeyuncached++; 151 sk = key_hash[KEYHASH(keyno)]; 152 while (sk != 0) { 153 if (keyno == sk->keyid) 154 break; 155 sk = sk->next; 156 } 157 if (sk == 0) { 158 authkeynotfound++; 159 return (0); 160 } else if (!(sk->flags & KEY_TRUSTED)) { 161 authnokey++; 162 return (0); 163 } 164 cache_keyid = sk->keyid; 165 cache_flags = sk->flags; 166 if (sk->flags & KEY_MD5) { 167 cache_key = sk->k.MD5_key; 168 cache_keylen = sk->keylen; 169 return (1); 170 } 171 #ifdef DES 172 if (sk->flags & KEY_DES) { 173 cache_key = (u_char *)sk->k.DES_key; 174 return (1); 175 } 176 #endif 177 return (0); 178 } 179 180 181 /* 182 * auth_moremem - get some more free key structures 183 */ 184 int 185 auth_moremem(void) 186 { 187 struct savekey *sk; 188 int i; 189 190 sk = (struct savekey *)calloc(MEMINC, sizeof(struct savekey)); 191 if (sk == 0) 192 return (0); 193 194 for (i = MEMINC; i > 0; i--) { 195 sk->next = authfreekeys; 196 authfreekeys = sk++; 197 } 198 authnumfreekeys += MEMINC; 199 return (authnumfreekeys); 200 } 201 202 203 /* 204 * authtrust - declare a key to be trusted/untrusted 205 */ 206 void 207 authtrust( 208 keyid_t keyno, 209 u_long trust 210 ) 211 { 212 struct savekey *sk; 213 214 #ifdef DEBUG 215 if (debug > 2) 216 printf("authtrust: keyid %08x life %lu\n", keyno, trust); 217 #endif 218 sk = key_hash[KEYHASH(keyno)]; 219 while (sk != 0) { 220 if (keyno == sk->keyid) 221 break; 222 sk = sk->next; 223 } 224 225 if (sk == 0 && !trust) 226 return; 227 228 if (sk != 0) { 229 if (cache_keyid == keyno) { 230 cache_flags = 0; 231 cache_keyid = 0; 232 } 233 234 if (trust > 0) { 235 sk->flags |= KEY_TRUSTED; 236 if (trust > 1) 237 sk->lifetime = current_time + trust; 238 else 239 sk->lifetime = 0; 240 return; 241 } 242 243 sk->flags &= ~KEY_TRUSTED; { 244 struct savekey *skp; 245 246 skp = key_hash[KEYHASH(keyno)]; 247 if (skp == sk) { 248 key_hash[KEYHASH(keyno)] = sk->next; 249 } else { 250 while (skp->next != sk) 251 skp = skp->next; 252 skp->next = sk->next; 253 } 254 authnumkeys--; 255 256 sk->next = authfreekeys; 257 authfreekeys = sk; 258 authnumfreekeys++; 259 } 260 return; 261 } 262 263 if (authnumfreekeys == 0) 264 if (auth_moremem() == 0) 265 return; 266 267 sk = authfreekeys; 268 authfreekeys = sk->next; 269 authnumfreekeys--; 270 271 sk->keyid = keyno; 272 sk->flags = KEY_TRUSTED; 273 sk->next = key_hash[KEYHASH(keyno)]; 274 key_hash[KEYHASH(keyno)] = sk; 275 authnumkeys++; 276 return; 277 } 278 279 280 /* 281 * authistrusted - determine whether a key is trusted 282 */ 283 int 284 authistrusted( 285 keyid_t keyno 286 ) 287 { 288 struct savekey *sk; 289 290 if (keyno == cache_keyid) 291 return ((cache_flags & KEY_TRUSTED) != 0); 292 293 authkeyuncached++; 294 sk = key_hash[KEYHASH(keyno)]; 295 while (sk != 0) { 296 if (keyno == sk->keyid) 297 break; 298 sk = sk->next; 299 } 300 if (sk == 0) { 301 authkeynotfound++; 302 return (0); 303 } else if (!(sk->flags & KEY_TRUSTED)) { 304 authkeynotfound++; 305 return (0); 306 } 307 return (1); 308 } 309 310 311 312 #ifdef DES 313 /* 314 * DESauth_setkey - set a key into the key array 315 */ 316 void 317 DESauth_setkey( 318 keyid_t keyno, 319 const u_int32 *key 320 ) 321 { 322 struct savekey *sk; 323 324 /* 325 * See if we already have the key. If so just stick in the 326 * new value. 327 */ 328 sk = key_hash[KEYHASH(keyno)]; 329 while (sk != 0) { 330 if (keyno == sk->keyid) { 331 sk->k.DES_key[0] = key[0]; 332 sk->k.DES_key[1] = key[1]; 333 sk->flags |= KEY_DES; 334 if (cache_keyid == keyno) 335 cache_flags = 0; 336 cache_keyid = 0; 337 return; 338 } 339 sk = sk->next; 340 } 341 342 /* 343 * Need to allocate new structure. Do it. 344 */ 345 if (authnumfreekeys == 0) { 346 if (auth_moremem() == 0) 347 return; 348 } 349 sk = authfreekeys; 350 authfreekeys = sk->next; 351 authnumfreekeys--; 352 353 sk->k.DES_key[0] = key[0]; 354 sk->k.DES_key[1] = key[1]; 355 sk->keyid = keyno; 356 sk->flags = KEY_DES; 357 sk->lifetime = 0; 358 sk->next = key_hash[KEYHASH(keyno)]; 359 key_hash[KEYHASH(keyno)] = sk; 360 authnumkeys++; 361 return; 362 } 363 #endif 364 365 void 366 MD5auth_setkey( 367 keyid_t keyno, 368 const u_char *key, 369 const int len 370 ) 371 { 372 struct savekey *sk; 373 374 /* 375 * See if we already have the key. If so just stick in the 376 * new value. 377 */ 378 sk = key_hash[KEYHASH(keyno)]; 379 while (sk != 0) { 380 if (keyno == sk->keyid) { 381 strncpy((char *)sk->k.MD5_key, (const char *)key, 382 sizeof(sk->k.MD5_key)); 383 if ((sk->keylen = len) > sizeof(sk->k.MD5_key)) 384 sk->keylen = sizeof(sk->k.MD5_key); 385 386 sk->flags |= KEY_MD5; 387 if (cache_keyid == keyno) { 388 cache_flags = 0; 389 cache_keyid = 0; 390 } 391 return; 392 } 393 sk = sk->next; 394 } 395 396 /* 397 * Need to allocate new structure. Do it. 398 */ 399 if (authnumfreekeys == 0) { 400 if (auth_moremem() == 0) 401 return; 402 } 403 404 sk = authfreekeys; 405 authfreekeys = sk->next; 406 authnumfreekeys--; 407 408 strncpy((char *)sk->k.MD5_key, (const char *)key, 409 sizeof(sk->k.MD5_key)); 410 if ((sk->keylen = len) > sizeof(sk->k.MD5_key)) 411 sk->keylen = sizeof(sk->k.MD5_key); 412 413 sk->keyid = keyno; 414 sk->flags = KEY_MD5; 415 sk->lifetime = 0; 416 sk->next = key_hash[KEYHASH(keyno)]; 417 key_hash[KEYHASH(keyno)] = sk; 418 authnumkeys++; 419 return; 420 } 421 422 /* 423 * auth_delkeys - delete all known keys, in preparation for rereading 424 * the keys file (presumably) 425 */ 426 void 427 auth_delkeys(void) 428 { 429 struct savekey *sk; 430 struct savekey **skp; 431 int i; 432 433 for (i = 0; i < HASHSIZE; i++) { 434 skp = &(key_hash[i]); 435 sk = key_hash[i]; 436 /* 437 * Leave autokey keys alone. 438 */ 439 while (sk != 0 && sk->keyid <= NTP_MAXKEY) { 440 /* 441 * Don't loose info which keys are trusted. 442 */ 443 if (sk->flags & KEY_TRUSTED) { 444 memset(&sk->k, 0, sizeof(sk->k)); 445 sk->lifetime = 0; 446 sk->keylen = 0; 447 sk = sk->next; 448 } else { 449 *skp = sk->next; 450 authnumkeys--; 451 sk->next = authfreekeys; 452 authfreekeys = sk; 453 authnumfreekeys++; 454 sk = *skp; 455 } 456 } 457 } 458 } 459 460 /* 461 * auth_agekeys - delete keys whose lifetimes have expired 462 */ 463 void 464 auth_agekeys(void) 465 { 466 struct savekey *sk; 467 struct savekey *skp; 468 int i; 469 470 for (i = 0; i < HASHSIZE; i++) { 471 sk = skp = key_hash[i]; 472 while (sk != 0) { 473 skp = sk->next; 474 if (sk->lifetime > 0 && current_time > 475 sk->lifetime) { 476 authtrust(sk->keyid, 0); 477 authkeyexpired++; 478 } 479 sk = skp; 480 } 481 } 482 #ifdef DEBUG 483 if (debug) 484 printf("auth_agekeys: at %lu keys %lu expired %lu\n", 485 current_time, authnumkeys, authkeyexpired); 486 #endif 487 } 488 489 /* 490 * authencrypt - generate message authenticator 491 * 492 * Returns length of authenticator field, zero if key not found. 493 */ 494 int 495 authencrypt( 496 keyid_t keyno, 497 u_int32 *pkt, 498 int length 499 ) 500 { 501 502 /* 503 * A zero key identifier means the sender has not verified 504 * the last message was correctly authenticated. The MAC 505 * consists of a single word with value zero. 506 */ 507 authencryptions++; 508 pkt[length / 4] = htonl(keyno); 509 if (keyno == 0) { 510 return (4); 511 } 512 if (!authhavekey(keyno)) 513 return (0); 514 515 #ifdef DES 516 if (cache_flags & KEY_DES) 517 return (DESauthencrypt(cache_key, pkt, length)); 518 #endif 519 520 if (cache_flags & KEY_MD5) 521 return (MD5authencrypt(cache_key, pkt, length)); 522 523 return (0); 524 } 525 526 /* 527 * authdecrypt - verify message authenticator 528 * 529 * Returns one if authenticator valid, zero if invalid or key not found. 530 */ 531 int 532 authdecrypt( 533 keyid_t keyno, 534 u_int32 *pkt, 535 int length, 536 int size 537 ) 538 { 539 540 /* 541 * A zero key identifier means the sender has not verified 542 * the last message was correctly authenticated. Nevertheless, 543 * the authenticator itself is considered valid. 544 */ 545 authdecryptions++; 546 if (keyno == 0) 547 return (0); 548 549 if (!authhavekey(keyno) || size < 4) 550 return (0); 551 552 #ifdef DES 553 if (cache_flags & KEY_DES) 554 return (DESauthdecrypt(cache_key, pkt, length, size)); 555 #endif 556 557 if (cache_flags & KEY_MD5) 558 return (MD5authdecrypt(cache_key, pkt, length, size)); 559 560 return (0); 561 } 562