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