1 /* 2 * This file is part of DGD, https://github.com/dworkin/dgd 3 * Copyright (C) 1993-2010 Dworkin B.V. 4 * Copyright (C) 2010-2012 DGD Authors (see the commit log for details) 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU Affero General Public License as 8 * published by the Free Software Foundation, either version 3 of the 9 * License, or (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU Affero General Public License for more details. 15 * 16 * You should have received a copy of the GNU Affero General Public License 17 * along with this program. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 # ifndef FUNCDEF 21 # define INCLUDE_CTYPE 22 # include "kfun.h" 23 # include "parse.h" 24 # include "asn.h" 25 # endif 26 27 # ifdef FUNCDEF 28 FUNCDEF("encrypt", kf_encrypt, pt_encrypt, 0) 29 # else 30 extern string *P_encrypt_des_key (frame*, string*); 31 extern string *P_encrypt_des (frame*, string*, string*); 32 33 char pt_encrypt[] = { C_TYPECHECKED | C_STATIC, 2, 1, 0, 9, T_MIXED, T_STRING, 34 T_STRING, T_STRING }; 35 36 /* 37 * NAME: kfun->enc_key() 38 * DESCRIPTION: prepare a key for encryption 39 */ 40 void kf_enc_key(frame *f, int nargs, value *val) 41 { 42 string *str; 43 44 if (nargs != 1) { 45 error("Too many arguments for kfun encrypt"); 46 } 47 str = P_encrypt_des_key(f, f->sp->u.string); 48 PUT_STRVAL_NOREF(val, str); 49 } 50 51 /* 52 * NAME: kfun->enc() 53 * DESCRIPTION: encrypt 54 */ 55 void kf_enc(frame *f, int nargs, value *val) 56 { 57 string *str; 58 59 if (nargs != 2) { 60 error("Too few arguments for kfun encrypt"); 61 } 62 str = P_encrypt_des(f, f->sp[1].u.string, f->sp->u.string); 63 PUT_STRVAL_NOREF(val, str); 64 } 65 # endif 66 67 68 # ifdef FUNCDEF 69 FUNCDEF("decrypt", kf_decrypt, pt_decrypt, 0) 70 # else 71 extern string *P_decrypt_des_key (frame*, string*); 72 73 char pt_decrypt[] = { C_TYPECHECKED | C_STATIC, 2, 1, 0, 9, T_MIXED, T_STRING, 74 T_STRING, T_STRING }; 75 76 /* 77 * NAME: kfun->dec_key() 78 * DESCRIPTION: prepare a key for decryption 79 */ 80 void kf_dec_key(frame *f, int nargs, value *val) 81 { 82 string *str; 83 84 if (nargs != 1) { 85 error("Too many arguments for kfun decrypt"); 86 } 87 str = P_decrypt_des_key(f, f->sp->u.string); 88 PUT_STRVAL_NOREF(val, str); 89 } 90 91 /* 92 * NAME: kfun->dec() 93 * DESCRIPTION: decrypt 94 */ 95 void kf_dec(frame *f, int nargs, value *val) 96 { 97 string *str; 98 99 if (nargs != 2) { 100 error("Too few arguments for kfun decrypt"); 101 } 102 /* Given the proper key, DES is its own inverse */ 103 str = P_encrypt_des(f, f->sp[1].u.string, f->sp->u.string); 104 PUT_STRVAL_NOREF(val, str); 105 } 106 # endif 107 108 109 # ifdef FUNCDEF 110 FUNCDEF("ctime", kf_ctime, pt_ctime, 0) 111 # else 112 char pt_ctime[] = { C_TYPECHECKED | C_STATIC, 1, 0, 0, 7, T_STRING, T_INT }; 113 114 /* 115 * NAME: kfun->ctime() 116 * DESCRIPTION: convert a time value to a string 117 */ 118 int kf_ctime(frame *f) 119 { 120 char buf[26]; 121 122 i_add_ticks(f, 5); 123 P_ctime(buf, f->sp->u.number); 124 PUT_STRVAL(f->sp, str_new(buf, 24L)); 125 126 return 0; 127 } 128 # endif 129 130 131 # ifdef FUNCDEF 132 FUNCDEF("explode", kf_explode, pt_explode, 0) 133 # else 134 char pt_explode[] = { C_TYPECHECKED | C_STATIC, 2, 0, 0, 8, 135 T_STRING | (1 << REFSHIFT), T_STRING, T_STRING }; 136 137 /* 138 * NAME: kfun->explode() 139 * DESCRIPTION: explode a string 140 */ 141 int kf_explode(frame *f) 142 { 143 unsigned int len, slen, size; 144 char *p, *s; 145 value *v; 146 array *a; 147 148 p = f->sp[1].u.string->text; 149 len = f->sp[1].u.string->len; 150 s = f->sp->u.string->text; 151 slen = f->sp->u.string->len; 152 153 if (len == 0) { 154 /* 155 * exploding "" always gives an empty array 156 */ 157 a = arr_new(f->data, 0L); 158 } else if (slen == 0) { 159 /* 160 * the sepatator is ""; split string into single characters 161 */ 162 a = arr_new(f->data, (long) len); 163 for (v = a->elts; len > 0; v++, --len) { 164 PUT_STRVAL(v, str_new(p, 1L)); 165 p++; 166 } 167 } else { 168 /* 169 * split up the string with the separator 170 */ 171 size = 1; 172 if (len >= slen && memcmp(p, s, slen) == 0) { 173 /* skip leading separator */ 174 p += slen; 175 len -= slen; 176 } 177 while (len > slen) { 178 if (memcmp(p, s, slen) == 0) { 179 /* separator found */ 180 p += slen; 181 len -= slen; 182 size++; 183 } else { 184 /* next char */ 185 p++; 186 --len; 187 } 188 } 189 190 a = arr_new(f->data, (long) size); 191 v = a->elts; 192 193 p = f->sp[1].u.string->text; 194 len = f->sp[1].u.string->len; 195 size = 0; 196 if (len > slen && memcmp(p, s, slen) == 0) { 197 /* skip leading separator */ 198 p += slen; 199 len -= slen; 200 } 201 while (len > slen) { 202 if (memcmp(p, s, slen) == 0) { 203 /* separator found */ 204 PUT_STRVAL(v, str_new(p - size, (long) size)); 205 v++; 206 p += slen; 207 len -= slen; 208 size = 0; 209 } else { 210 /* next char */ 211 p++; 212 --len; 213 size++; 214 } 215 } 216 if (len != slen || memcmp(p, s, slen) != 0) { 217 /* remainder isn't a sepatator */ 218 size += len; 219 p += len; 220 } 221 /* final array element */ 222 PUT_STRVAL(v, str_new(p - size, (long) size)); 223 } 224 225 str_del((f->sp++)->u.string); 226 str_del(f->sp->u.string); 227 PUT_ARRVAL(f->sp, a); 228 i_add_ticks(f, (Int) 2 * a->size); 229 230 return 0; 231 } 232 # endif 233 234 235 # ifdef FUNCDEF 236 FUNCDEF("implode", kf_implode, pt_implode, 0) 237 # else 238 char pt_implode[] = { C_TYPECHECKED | C_STATIC, 2, 0, 0, 8, T_STRING, 239 T_STRING | (1 << REFSHIFT), T_STRING }; 240 241 /* 242 * NAME: kfun->implode() 243 * DESCRIPTION: implode an array 244 */ 245 int kf_implode(frame *f) 246 { 247 long len; 248 unsigned int i, slen; 249 char *p, *s; 250 value *v; 251 string *str; 252 253 s = f->sp->u.string->text; 254 slen = f->sp->u.string->len; 255 256 /* first, determine the size of the imploded string */ 257 i = f->sp[1].u.array->size; 258 i_add_ticks(f, i); 259 if (i != 0) { 260 len = (i - 1) * (long) slen; /* size of all separators */ 261 for (v = d_get_elts(f->sp[1].u.array); i > 0; v++, --i) { 262 if (v->type != T_STRING) { 263 /* not a (string *) */ 264 return 1; 265 } 266 len += v->u.string->len; 267 } 268 str = str_new((char *) NULL, len); 269 270 /* create the imploded string */ 271 p = str->text; 272 for (i = f->sp[1].u.array->size, v -= i; i > 1; --i, v++) { 273 /* copy array part */ 274 memcpy(p, v->u.string->text, v->u.string->len); 275 p += v->u.string->len; 276 /* copy separator */ 277 memcpy(p, s, slen); 278 p += slen; 279 } 280 /* copy final array part */ 281 memcpy(p, v->u.string->text, v->u.string->len); 282 } else { 283 /* zero size array gives zero size string */ 284 str = str_new((char *) NULL, 0L); 285 } 286 287 str_del((f->sp++)->u.string); 288 arr_del(f->sp->u.array); 289 PUT_STRVAL(f->sp, str); 290 return 0; 291 } 292 # endif 293 294 295 # ifdef FUNCDEF 296 FUNCDEF("random", kf_random, pt_random, 0) 297 # else 298 char pt_random[] = { C_TYPECHECKED | C_STATIC, 1, 0, 0, 7, T_INT, T_INT }; 299 300 /* 301 * NAME: kfun->random() 302 * DESCRIPTION: return a random number 303 */ 304 int kf_random(frame *f) 305 { 306 i_add_ticks(f, 1); 307 PUT_INT(f->sp, (f->sp->u.number > 0) ? P_random() % f->sp->u.number : 0); 308 return 0; 309 } 310 # endif 311 312 313 # ifdef FUNCDEF 314 FUNCDEF("sscanf", kf_sscanf, pt_sscanf, 0) 315 # else 316 char pt_sscanf[] = { C_STATIC | C_ELLIPSIS, 2, 1, 0, 9, T_INT, T_STRING, 317 T_STRING, T_LVALUE }; 318 319 /* 320 * NAME: match 321 * DESCRIPTION: match a string possibly including %%, up to the next %[sdfc] or 322 * the end of the string 323 */ 324 static bool match(char *f, char *s, unsigned int *flenp, unsigned int *slenp) 325 { 326 char *p; 327 unsigned int flen, slen; 328 329 flen = *flenp; 330 slen = *slenp; 331 332 while (flen > 0) { 333 /* look for first % */ 334 p = (char *) memchr(f, '%', flen); 335 336 if (p == (char *) NULL) { 337 /* no remaining % */ 338 if (memcmp(f, s, flen) == 0) { 339 *slenp -= slen - flen; 340 return TRUE; 341 } else { 342 return FALSE; /* no match */ 343 } 344 } 345 346 if (p[1] == '%') { 347 /* %% */ 348 if (memcmp(f, s, ++p - f) == 0) { 349 /* matched up to and including the first % */ 350 s += p - f; 351 slen -= p - f; 352 flen -= ++p - f; 353 f = p; 354 } else { 355 return FALSE; /* no match */ 356 } 357 } else if (memcmp(f, s, p - f) == 0) { 358 /* matched up to the first % */ 359 *flenp -= flen - (p - f); 360 *slenp -= slen - (p - f); 361 return TRUE; 362 } else { 363 return FALSE; /* no match */ 364 } 365 } 366 367 *slenp -= slen; 368 return TRUE; 369 } 370 371 /* 372 * NAME: kfun->sscanf() 373 * DESCRIPTION: scan a string 374 */ 375 int kf_sscanf(frame *f, int nargs) 376 { 377 unsigned int flen, slen, size; 378 char *format, *x; 379 unsigned int fl, sl; 380 int matches; 381 char *s; 382 Int i; 383 xfloat flt; 384 bool skip; 385 value *top, *v; 386 387 size = 0; 388 x = NULL; 389 390 if (nargs < 2) { 391 return -1; 392 } 393 nargs -= 2; 394 if (nargs > MAX_LOCALS) { 395 return 4; 396 } 397 top = i_reverse(f, nargs); 398 if (top[1].type != T_STRING) { 399 return 1; 400 } 401 s = top[1].u.string->text; 402 slen = top[1].u.string->len; 403 if (top[0].type != T_STRING) { 404 return 2; 405 } 406 format = top[0].u.string->text; 407 flen = top[0].u.string->len; 408 409 i_add_ticks(f, 8 * nargs); 410 matches = 0; 411 412 while (flen > 0) { 413 if (format[0] != '%' || format[1] == '%') { 414 /* match initial part */ 415 fl = flen; 416 sl = slen; 417 if (!match(format, s, &fl, &sl) || fl == flen) { 418 goto no_match; 419 } 420 format += fl; 421 flen -= fl; 422 s += sl; 423 slen -= sl; 424 } 425 426 /* skip first % */ 427 format++; 428 --flen; 429 430 /* 431 * check for %* 432 */ 433 if (*format == '*') { 434 /* no assignment */ 435 format++; 436 --flen; 437 skip = TRUE; 438 } else { 439 skip = FALSE; 440 } 441 442 --flen; 443 switch (*format++) { 444 case 's': 445 /* %s */ 446 if (format[0] == '%' && format[1] != '%') { 447 switch ((format[1] == '*') ? format[2] : format[1]) { 448 case 'd': 449 /* 450 * %s%d 451 */ 452 size = slen; 453 x = s; 454 while (!isdigit(*x)) { 455 if (slen == 0) { 456 goto no_match; 457 } 458 if (x[0] == '-' && isdigit(x[1])) { 459 break; 460 } 461 x++; 462 --slen; 463 } 464 size -= slen; 465 break; 466 467 case 'f': 468 /* 469 * %s%f 470 */ 471 size = slen; 472 x = s; 473 while (!isdigit(*x)) { 474 if (slen == 0) { 475 goto no_match; 476 } 477 if ((x[0] == '-' || x[0] == '.') && isdigit(x[1])) { 478 break; 479 } 480 x++; 481 --slen; 482 } 483 size -= slen; 484 break; 485 486 default: 487 error("Bad sscanf format string"); 488 } 489 } else { 490 /* 491 * %s followed by non-% 492 */ 493 if (flen == 0) { 494 /* match whole string */ 495 size = slen; 496 x = s + slen; 497 slen = 0; 498 } else { 499 /* get # of chars to match after string */ 500 for (x = format, size = 0; x - format != flen; 501 x++, size++) { 502 x = (char *) memchr(x, '%', flen - (x - format)); 503 if (x == (char *) NULL) { 504 x = format + flen; 505 break; 506 } else if (x[1] != '%') { 507 break; 508 } 509 } 510 size = (x - format) - size; 511 512 x = s; 513 for (;;) { 514 sl = slen - (x - s); 515 if (sl < size) { 516 goto no_match; 517 } 518 x = (char *) memchr(x, format[0], sl - size + 1); 519 if (x == (char *) NULL) { 520 goto no_match; 521 } 522 fl = flen; 523 if (match(format, x, &fl, &sl)) { 524 format += fl; 525 flen -= fl; 526 size = x - s; 527 x += sl; 528 slen -= size + sl; 529 break; 530 } 531 x++; 532 } 533 } 534 } 535 536 if (!skip) { 537 if (nargs == 0) { 538 error("No lvalue for %%s"); 539 } 540 --nargs; 541 PUSH_STRVAL(f, str_new(s, (long) size)); 542 v = f->sp; 543 i_store(f); 544 v->u.string->ref--; 545 } 546 s = x; 547 break; 548 549 case 'd': 550 /* %d */ 551 x = s; 552 while (slen != 0 && *x == ' ') { 553 x++; 554 --slen; 555 } 556 s = x; 557 i = strtoint(&s); 558 if (s == x) { 559 goto no_match; 560 } 561 slen -= (s - x); 562 563 if (!skip) { 564 if (nargs == 0) { 565 error("No lvalue for %%d"); 566 } 567 --nargs; 568 PUSH_INTVAL(f, i); 569 i_store(f); 570 } 571 break; 572 573 case 'f': 574 /* %f */ 575 x = s; 576 while (slen != 0 && *x == ' ') { 577 x++; 578 --slen; 579 } 580 s = x; 581 if (!flt_atof(&s, &flt) || s == x) { 582 goto no_match; 583 } 584 slen -= (s - x); 585 586 if (!skip) { 587 if (nargs == 0) { 588 error("No lvalue for %%f"); 589 } 590 --nargs; 591 PUSH_FLTVAL(f, flt); 592 i_store(f); 593 } 594 break; 595 596 case 'c': 597 /* %c */ 598 if (slen == 0) { 599 goto no_match; 600 } 601 if (!skip) { 602 if (nargs == 0) { 603 error("No lvalue for %%c"); 604 } 605 --nargs; 606 PUSH_INTVAL(f, UCHAR(*s)); 607 i_store(f); 608 } 609 s++; 610 --slen; 611 break; 612 613 default: 614 error("Bad sscanf format string"); 615 } 616 matches++; 617 } 618 619 no_match: 620 i_pop(f, top - f->sp + 2); 621 PUSH_INTVAL(f, matches); 622 return 0; 623 } 624 # endif 625 626 627 # ifdef FUNCDEF 628 FUNCDEF("parse_string", kf_parse_string, pt_parse_string, 0) 629 # else 630 char pt_parse_string[] = { C_TYPECHECKED | C_STATIC, 2, 1, 0, 9, 631 T_MIXED | (1 << REFSHIFT), T_STRING, T_STRING, 632 T_INT }; 633 634 /* 635 * NAME: kfun->parse_string() 636 * DESCRIPTION: parse a string 637 */ 638 int kf_parse_string(frame *f, int nargs) 639 { 640 Int maxalt; 641 array *a; 642 643 if (nargs > 2) { 644 maxalt = (f->sp++)->u.number + 1; 645 if (maxalt <= 0) { 646 return 3; 647 } 648 } else { 649 maxalt = 1; /* default: just one valid parse tree */ 650 } 651 652 if (OBJR(f->oindex)->flags & O_SPECIAL) { 653 error("parse_string() from special purpose object"); 654 } 655 656 a = ps_parse_string(f, f->sp[1].u.string, f->sp->u.string, maxalt); 657 str_del((f->sp++)->u.string); 658 str_del(f->sp->u.string); 659 660 if (a != (array *) NULL) { 661 /* return parse tree */ 662 PUT_ARRVAL(f->sp, a); 663 } else { 664 /* parsing failed */ 665 *f->sp = nil_value; 666 } 667 return 0; 668 } 669 # endif 670 671 672 # ifdef FUNCDEF 673 FUNCDEF("hash_crc16", kf_hash_crc16, pt_hash_crc16, 0) 674 # else 675 char pt_hash_crc16[] = { C_TYPECHECKED | C_STATIC | C_ELLIPSIS, 1, 1, 0, 8, 676 T_INT, T_STRING, T_STRING }; 677 678 /* 679 * NAME: kfun->hash_crc16() 680 * DESCRIPTION: Compute a 16 bit cyclic redundancy code for a string. 681 * Based on "A PAINLESS GUIDE TO CRC ERROR DETECTION ALGORITHMS", 682 * by Ross N. Williams. 683 * 684 * Name: "CRC-16/CCITT" (supposedly) 685 * Width: 16 686 * Poly: 1021 (X^16 + X^12 + X^5 + 1) 687 * Init: FFFF 688 * RefIn: False 689 * RefOut: False 690 * XorOut: 0000 691 * Check: 29B1 692 */ 693 int kf_hash_crc16(frame *f, int nargs) 694 { 695 static unsigned short crctab[] = { 696 0x0000, 0x2110, 0x4220, 0x6330, 0x8440, 0xa550, 0xc660, 0xe770, 697 0x0881, 0x2991, 0x4aa1, 0x6bb1, 0x8cc1, 0xadd1, 0xcee1, 0xeff1, 698 0x3112, 0x1002, 0x7332, 0x5222, 0xb552, 0x9442, 0xf772, 0xd662, 699 0x3993, 0x1883, 0x7bb3, 0x5aa3, 0xbdd3, 0x9cc3, 0xfff3, 0xdee3, 700 0x6224, 0x4334, 0x2004, 0x0114, 0xe664, 0xc774, 0xa444, 0x8554, 701 0x6aa5, 0x4bb5, 0x2885, 0x0995, 0xeee5, 0xcff5, 0xacc5, 0x8dd5, 702 0x5336, 0x7226, 0x1116, 0x3006, 0xd776, 0xf666, 0x9556, 0xb446, 703 0x5bb7, 0x7aa7, 0x1997, 0x3887, 0xdff7, 0xfee7, 0x9dd7, 0xbcc7, 704 0xc448, 0xe558, 0x8668, 0xa778, 0x4008, 0x6118, 0x0228, 0x2338, 705 0xccc9, 0xedd9, 0x8ee9, 0xaff9, 0x4889, 0x6999, 0x0aa9, 0x2bb9, 706 0xf55a, 0xd44a, 0xb77a, 0x966a, 0x711a, 0x500a, 0x333a, 0x122a, 707 0xfddb, 0xdccb, 0xbffb, 0x9eeb, 0x799b, 0x588b, 0x3bbb, 0x1aab, 708 0xa66c, 0x877c, 0xe44c, 0xc55c, 0x222c, 0x033c, 0x600c, 0x411c, 709 0xaeed, 0x8ffd, 0xeccd, 0xcddd, 0x2aad, 0x0bbd, 0x688d, 0x499d, 710 0x977e, 0xb66e, 0xd55e, 0xf44e, 0x133e, 0x322e, 0x511e, 0x700e, 711 0x9fff, 0xbeef, 0xdddf, 0xfccf, 0x1bbf, 0x3aaf, 0x599f, 0x788f, 712 0x8891, 0xa981, 0xcab1, 0xeba1, 0x0cd1, 0x2dc1, 0x4ef1, 0x6fe1, 713 0x8010, 0xa100, 0xc230, 0xe320, 0x0450, 0x2540, 0x4670, 0x6760, 714 0xb983, 0x9893, 0xfba3, 0xdab3, 0x3dc3, 0x1cd3, 0x7fe3, 0x5ef3, 715 0xb102, 0x9012, 0xf322, 0xd232, 0x3542, 0x1452, 0x7762, 0x5672, 716 0xeab5, 0xcba5, 0xa895, 0x8985, 0x6ef5, 0x4fe5, 0x2cd5, 0x0dc5, 717 0xe234, 0xc324, 0xa014, 0x8104, 0x6674, 0x4764, 0x2454, 0x0544, 718 0xdba7, 0xfab7, 0x9987, 0xb897, 0x5fe7, 0x7ef7, 0x1dc7, 0x3cd7, 719 0xd326, 0xf236, 0x9106, 0xb016, 0x5766, 0x7676, 0x1546, 0x3456, 720 0x4cd9, 0x6dc9, 0x0ef9, 0x2fe9, 0xc899, 0xe989, 0x8ab9, 0xaba9, 721 0x4458, 0x6548, 0x0678, 0x2768, 0xc018, 0xe108, 0x8238, 0xa328, 722 0x7dcb, 0x5cdb, 0x3feb, 0x1efb, 0xf98b, 0xd89b, 0xbbab, 0x9abb, 723 0x754a, 0x545a, 0x376a, 0x167a, 0xf10a, 0xd01a, 0xb32a, 0x923a, 724 0x2efd, 0x0fed, 0x6cdd, 0x4dcd, 0xaabd, 0x8bad, 0xe89d, 0xc98d, 725 0x267c, 0x076c, 0x645c, 0x454c, 0xa23c, 0x832c, 0xe01c, 0xc10c, 726 0x1fef, 0x3eff, 0x5dcf, 0x7cdf, 0x9baf, 0xbabf, 0xd98f, 0xf89f, 727 0x176e, 0x367e, 0x554e, 0x745e, 0x932e, 0xb23e, 0xd10e, 0xf01e 728 }; 729 unsigned short crc; 730 int i; 731 ssizet len; 732 char *p; 733 Int cost; 734 735 cost = 0; 736 for (i = nargs; --i >= 0; ) { 737 cost += f->sp[i].u.string->len; 738 } 739 cost = 3 * nargs + (cost >> 2); 740 if (!f->rlim->noticks && f->rlim->ticks <= cost) { 741 f->rlim->ticks = 0; 742 error("Out of ticks"); 743 } 744 i_add_ticks(f, cost); 745 746 crc = 0xffff; 747 for (i = nargs; --i >= 0; ) { 748 p = f->sp[i].u.string->text; 749 for (len = f->sp[i].u.string->len; len != 0; --len) { 750 crc = (crc >> 8) ^ crctab[UCHAR(crc ^ *p++)]; 751 } 752 str_del(f->sp[i].u.string); 753 } 754 crc = (crc >> 8) + (crc << 8); 755 756 f->sp += nargs - 1; 757 PUT_INTVAL(f->sp, crc); 758 return 0; 759 } 760 # endif 761 762 763 # ifdef FUNCDEF 764 FUNCDEF("hash_crc32", kf_hash_crc32, pt_hash_crc32, 0) 765 # else 766 char pt_hash_crc32[] = { C_TYPECHECKED | C_STATIC | C_ELLIPSIS, 1, 1, 0, 8, 767 T_INT, T_STRING, T_STRING }; 768 769 /* 770 * NAME: kfun->hash_crc32() 771 * DESCRIPTION: Compute a 32 bit cyclic redundancy code for a string. 772 * Based on "A PAINLESS GUIDE TO CRC ERROR DETECTION ALGORITHMS", 773 * by Ross N. Williams. 774 * 775 * Name: "CRC-32" (as in libz) 776 * Width: 16 777 * Poly: 04C11DB7 778 * Init: FFFFFFFF 779 * RefIn: True 780 * RefOut: True 781 * XorOut: FFFFFFFF 782 * Check: CBF43926 783 */ 784 int kf_hash_crc32(frame *f, int nargs) 785 { 786 static Uint crctab[] = { 787 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, 788 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, 789 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 790 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, 791 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, 792 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, 793 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 794 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, 795 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, 796 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, 797 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 798 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, 799 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, 800 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, 801 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 802 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, 803 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, 804 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, 805 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 806 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, 807 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, 808 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, 809 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, 810 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, 811 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, 812 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, 813 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, 814 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, 815 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, 816 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, 817 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 818 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, 819 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, 820 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, 821 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 822 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, 823 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, 824 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, 825 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 826 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, 827 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, 828 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, 829 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 830 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, 831 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, 832 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, 833 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 834 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, 835 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, 836 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, 837 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 838 0x2d02ef8dL 839 }; 840 Uint crc; 841 int i; 842 ssizet len; 843 char *p; 844 Int cost; 845 846 cost = 0; 847 for (i = nargs; --i >= 0; ) { 848 cost += f->sp[i].u.string->len; 849 } 850 cost = 3 * nargs + (cost >> 2); 851 if (!f->rlim->noticks && f->rlim->ticks <= cost) { 852 f->rlim->ticks = 0; 853 error("Out of ticks"); 854 } 855 i_add_ticks(f, cost); 856 857 crc = 0xffffffff; 858 for (i = nargs; --i >= 0; ) { 859 p = f->sp[i].u.string->text; 860 for (len = f->sp[i].u.string->len; len != 0; --len) { 861 crc = (crc >> 8) ^ crctab[UCHAR(crc ^ *p++)]; 862 } 863 str_del(f->sp[i].u.string); 864 } 865 crc ^= 0xffffffffL; 866 867 f->sp += nargs - 1; 868 PUT_INTVAL(f->sp, crc); 869 return 0; 870 } 871 # endif 872 873 874 # ifdef FUNCDEF 875 FUNCDEF("hash_string", kf_hash_string, pt_hash_string, 0) 876 # else 877 extern char *P_crypt (char*, char*); 878 879 char pt_hash_string[] = { C_TYPECHECKED | C_STATIC | C_ELLIPSIS, 2, 1, 0, 9, 880 T_STRING, T_STRING, T_STRING, T_STRING }; 881 882 /* 883 * NAME: kfun->xcrypt() 884 * DESCRIPTION: hash a string with Unix password crypt 885 */ 886 void kf_xcrypt(frame *f, int nargs, value *val) 887 { 888 static char salts[] = 889 "0123456789./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 890 char s[3]; 891 string *str; 892 893 if (nargs > 2) { 894 error("Too many arguments for kfun hash_string"); 895 } 896 if (nargs == 2 && f->sp->u.string->len >= 2) { 897 /* fixed salt */ 898 s[0] = f->sp->u.string->text[0]; 899 s[1] = f->sp->u.string->text[1]; 900 } else { 901 Uint n; 902 903 /* random salt */ 904 n = P_random(); 905 s[0] = salts[n & 63]; 906 s[1] = salts[(n >> 8) & 63]; 907 } 908 s[2] = '\0'; 909 910 i_add_ticks(f, 900); 911 str = str_new(P_crypt(f->sp[nargs - 1].u.string->text, s), 13); 912 PUT_STRVAL_NOREF(val, str); 913 } 914 915 # define ROTL(x, s) (((x) << s) | ((x) >> (32 - s))) 916 # define R1(a, b, c, d, Mj, s, ti) (a += (((c ^ d) & b) ^ d) + Mj + ti, \ 917 a = b + ROTL(a, s)) 918 # define R2(a, b, c, d, Mj, s, ti) (a += (((b ^ c) & d) ^ c) + Mj + ti, \ 919 a = b + ROTL(a, s)) 920 # define R3(a, b, c, d, Mj, s, ti) (a += (b ^ c ^ d) + Mj + ti, \ 921 a = b + ROTL(a, s)) 922 # define R4(a, b, c, d, Mj, s, ti) (a += (c ^ (b | ~d)) + Mj + ti, \ 923 a = b + ROTL(a, s)) 924 925 /* 926 * NAME: hash->md5_start() 927 * DESCRIPTION: MD5 message digest. See "Applied Cryptography" by Bruce 928 * Schneier, Second Edition, p. 436-441. 929 */ 930 static Int hash_md5_start(frame *f, int nargs, Uint *digest) 931 { 932 Int cost; 933 934 /* 935 * These constants must apparently be little-endianized, though AC2 does 936 * not explicitly say so. 937 */ 938 digest[0] = 0x67452301L; 939 digest[1] = 0xefcdab89L; 940 digest[2] = 0x98badcfeL; 941 digest[3] = 0x10325476L; 942 943 cost = 3 * nargs + 64; 944 while (--nargs >= 0) { 945 cost += f->sp[nargs].u.string->len; 946 } 947 return cost; 948 } 949 950 /* 951 * NAME: hash->md5_block() 952 * DESCRIPTION: add another 512 bit block to the message digest 953 */ 954 static void hash_md5_block(Uint *ABCD, char *block) 955 { 956 Uint M[16]; 957 int i, j; 958 Uint a, b, c, d; 959 960 for (i = j = 0; i < 16; i++, j += 4) { 961 M[i] = UCHAR(block[j + 0]) | (UCHAR(block[j + 1]) << 8) | 962 (UCHAR(block[j + 2]) << 16) | (UCHAR(block[j + 3]) << 24); 963 964 } 965 966 a = ABCD[0]; 967 b = ABCD[1]; 968 c = ABCD[2]; 969 d = ABCD[3]; 970 971 R1(a, b, c, d, M[ 0], 7, 0xd76aa478L); 972 R1(d, a, b, c, M[ 1], 12, 0xe8c7b756L); 973 R1(c, d, a, b, M[ 2], 17, 0x242070dbL); 974 R1(b, c, d, a, M[ 3], 22, 0xc1bdceeeL); 975 R1(a, b, c, d, M[ 4], 7, 0xf57c0fafL); 976 R1(d, a, b, c, M[ 5], 12, 0x4787c62aL); 977 R1(c, d, a, b, M[ 6], 17, 0xa8304613L); 978 R1(b, c, d, a, M[ 7], 22, 0xfd469501L); 979 R1(a, b, c, d, M[ 8], 7, 0x698098d8L); 980 R1(d, a, b, c, M[ 9], 12, 0x8b44f7afL); 981 R1(c, d, a, b, M[10], 17, 0xffff5bb1L); 982 R1(b, c, d, a, M[11], 22, 0x895cd7beL); 983 R1(a, b, c, d, M[12], 7, 0x6b901122L); 984 R1(d, a, b, c, M[13], 12, 0xfd987193L); 985 R1(c, d, a, b, M[14], 17, 0xa679438eL); 986 R1(b, c, d, a, M[15], 22, 0x49b40821L); 987 988 R2(a, b, c, d, M[ 1], 5, 0xf61e2562L); 989 R2(d, a, b, c, M[ 6], 9, 0xc040b340L); 990 R2(c, d, a, b, M[11], 14, 0x265e5a51L); 991 R2(b, c, d, a, M[ 0], 20, 0xe9b6c7aaL); 992 R2(a, b, c, d, M[ 5], 5, 0xd62f105dL); 993 R2(d, a, b, c, M[10], 9, 0x02441453L); 994 R2(c, d, a, b, M[15], 14, 0xd8a1e681L); 995 R2(b, c, d, a, M[ 4], 20, 0xe7d3fbc8L); 996 R2(a, b, c, d, M[ 9], 5, 0x21e1cde6L); 997 R2(d, a, b, c, M[14], 9, 0xc33707d6L); 998 R2(c, d, a, b, M[ 3], 14, 0xf4d50d87L); 999 R2(b, c, d, a, M[ 8], 20, 0x455a14edL); 1000 R2(a, b, c, d, M[13], 5, 0xa9e3e905L); 1001 R2(d, a, b, c, M[ 2], 9, 0xfcefa3f8L); 1002 R2(c, d, a, b, M[ 7], 14, 0x676f02d9L); 1003 R2(b, c, d, a, M[12], 20, 0x8d2a4c8aL); 1004 1005 R3(a, b, c, d, M[ 5], 4, 0xfffa3942L); 1006 R3(d, a, b, c, M[ 8], 11, 0x8771f681L); 1007 R3(c, d, a, b, M[11], 16, 0x6d9d6122L); 1008 R3(b, c, d, a, M[14], 23, 0xfde5380cL); 1009 R3(a, b, c, d, M[ 1], 4, 0xa4beea44L); 1010 R3(d, a, b, c, M[ 4], 11, 0x4bdecfa9L); 1011 R3(c, d, a, b, M[ 7], 16, 0xf6bb4b60L); 1012 R3(b, c, d, a, M[10], 23, 0xbebfbc70L); 1013 R3(a, b, c, d, M[13], 4, 0x289b7ec6L); 1014 R3(d, a, b, c, M[ 0], 11, 0xeaa127faL); 1015 R3(c, d, a, b, M[ 3], 16, 0xd4ef3085L); 1016 R3(b, c, d, a, M[ 6], 23, 0x04881d05L); 1017 R3(a, b, c, d, M[ 9], 4, 0xd9d4d039L); 1018 R3(d, a, b, c, M[12], 11, 0xe6db99e5L); 1019 R3(c, d, a, b, M[15], 16, 0x1fa27cf8L); 1020 R3(b, c, d, a, M[ 2], 23, 0xc4ac5665L); 1021 1022 R4(a, b, c, d, M[ 0], 6, 0xf4292244L); 1023 R4(d, a, b, c, M[ 7], 10, 0x432aff97L); 1024 R4(c, d, a, b, M[14], 15, 0xab9423a7L); 1025 R4(b, c, d, a, M[ 5], 21, 0xfc93a039L); 1026 R4(a, b, c, d, M[12], 6, 0x655b59c3L); 1027 R4(d, a, b, c, M[ 3], 10, 0x8f0ccc92L); 1028 R4(c, d, a, b, M[10], 15, 0xffeff47dL); 1029 R4(b, c, d, a, M[ 1], 21, 0x85845dd1L); 1030 R4(a, b, c, d, M[ 8], 6, 0x6fa87e4fL); 1031 R4(d, a, b, c, M[15], 10, 0xfe2ce6e0L); 1032 R4(c, d, a, b, M[ 6], 15, 0xa3014314L); 1033 R4(b, c, d, a, M[13], 21, 0x4e0811a1L); 1034 R4(a, b, c, d, M[ 4], 6, 0xf7537e82L); 1035 R4(d, a, b, c, M[11], 10, 0xbd3af235L); 1036 R4(c, d, a, b, M[ 2], 15, 0x2ad7d2bbL); 1037 R4(b, c, d, a, M[ 9], 21, 0xeb86d391L); 1038 1039 ABCD[0] += a; 1040 ABCD[1] += b; 1041 ABCD[2] += c; 1042 ABCD[3] += d; 1043 } 1044 1045 /* 1046 * NAME: hash->md5_end() 1047 * DESCRIPTION: finish up MD5 hash 1048 */ 1049 static string *hash_md5_end(Uint *digest, char *buffer, unsigned int bufsz, Uint length) 1050 { 1051 int i; 1052 1053 /* append padding and digest final block(s) */ 1054 buffer[bufsz++] = 0x80; 1055 if (bufsz > 56) { 1056 memset(buffer + bufsz, '\0', 64 - bufsz); 1057 hash_md5_block(digest, buffer); 1058 bufsz = 0; 1059 } 1060 memset(buffer + bufsz, '\0', 64 - bufsz); 1061 buffer[56] = length << 3; 1062 buffer[57] = length >> 5; 1063 buffer[58] = length >> 13; 1064 buffer[59] = length >> 21; 1065 buffer[60] = length >> 29; 1066 hash_md5_block(digest, buffer); 1067 1068 for (bufsz = i = 0; i < 4; bufsz += 4, i++) { 1069 buffer[bufsz + 0] = digest[i]; 1070 buffer[bufsz + 1] = digest[i] >> 8; 1071 buffer[bufsz + 2] = digest[i] >> 16; 1072 buffer[bufsz + 3] = digest[i] >> 24; 1073 } 1074 return str_new(buffer, 16L); 1075 } 1076 1077 /* 1078 * NAME: hash->sha1_start() 1079 * DESCRIPTION: SHA-1 message digest. See FIPS 180-2. 1080 */ 1081 static Int hash_sha1_start(frame *f, int nargs, Uint *digest) 1082 { 1083 Int cost; 1084 1085 digest[0] = 0x67452301L; 1086 digest[1] = 0xefcdab89L; 1087 digest[2] = 0x98badcfeL; 1088 digest[3] = 0x10325476L; 1089 digest[4] = 0xc3d2e1f0L; 1090 1091 cost = 3 * nargs + 64; 1092 while (--nargs >= 0) { 1093 cost += f->sp[nargs].u.string->len; 1094 } 1095 return cost; 1096 } 1097 1098 /* 1099 * NAME: hash->sha1_block() 1100 * DESCRIPTION: add another 512 bit block to the message digest 1101 */ 1102 static void hash_sha1_block(Uint *ABCDE, char *block) 1103 { 1104 Uint W[80]; 1105 int i, j; 1106 Uint a, b, c, d, e, t; 1107 1108 for (i = j = 0; i < 16; i++, j += 4) { 1109 W[i] = (UCHAR(block[j + 0]) << 24) | (UCHAR(block[j + 1]) << 16) | 1110 (UCHAR(block[j + 2]) << 8) | UCHAR(block[j + 3]); 1111 1112 } 1113 while (i < 80) { 1114 W[i] = ROTL(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1); 1115 i++; 1116 } 1117 1118 a = ABCDE[0]; 1119 b = ABCDE[1]; 1120 c = ABCDE[2]; 1121 d = ABCDE[3]; 1122 e = ABCDE[4]; 1123 1124 for (i = 0; i < 20; i++) { 1125 t = ROTL(a, 5) + (((c ^ d) & b) ^ d) + e + W[i] + 0x5a827999L; 1126 e = d; 1127 d = c; 1128 c = ROTL(b, 30); 1129 b = a; 1130 a = t; 1131 } 1132 while (i < 40) { 1133 t = ROTL(a, 5) + (b ^ c ^ d) + e + W[i] + 0x6ed9eba1L; 1134 e = d; 1135 d = c; 1136 c = ROTL(b, 30); 1137 b = a; 1138 a = t; 1139 i++; 1140 } 1141 while (i < 60) { 1142 t = ROTL(a, 5) + ((b & c) | ((b | c) & d)) + e + W[i] + 0x8f1bbcdcL; 1143 e = d; 1144 d = c; 1145 c = ROTL(b, 30); 1146 b = a; 1147 a = t; 1148 i++; 1149 } 1150 while (i < 80) { 1151 t = ROTL(a, 5) + (b ^ c ^ d) + e + W[i] + 0xca62c1d6L; 1152 e = d; 1153 d = c; 1154 c = ROTL(b, 30); 1155 b = a; 1156 a = t; 1157 i++; 1158 } 1159 1160 ABCDE[0] += a; 1161 ABCDE[1] += b; 1162 ABCDE[2] += c; 1163 ABCDE[3] += d; 1164 ABCDE[4] += e; 1165 } 1166 1167 1168 /* 1169 * NAME: hash->sha1_end() 1170 * DESCRIPTION: finish up SHA-1 hash 1171 */ 1172 static string *hash_sha1_end(Uint *digest, char *buffer, unsigned int bufsz, Uint length) 1173 { 1174 int i; 1175 1176 /* append padding and digest final block(s) */ 1177 buffer[bufsz++] = 0x80; 1178 if (bufsz > 56) { 1179 memset(buffer + bufsz, '\0', 64 - bufsz); 1180 hash_sha1_block(digest, buffer); 1181 bufsz = 0; 1182 } 1183 memset(buffer + bufsz, '\0', 64 - bufsz); 1184 buffer[59] = length >> 29; 1185 buffer[60] = length >> 21; 1186 buffer[61] = length >> 13; 1187 buffer[62] = length >> 5; 1188 buffer[63] = length << 3; 1189 hash_sha1_block(digest, buffer); 1190 1191 for (bufsz = i = 0; i < 5; bufsz += 4, i++) { 1192 buffer[bufsz + 0] = digest[i] >> 24; 1193 buffer[bufsz + 1] = digest[i] >> 16; 1194 buffer[bufsz + 2] = digest[i] >> 8; 1195 buffer[bufsz + 3] = digest[i]; 1196 } 1197 return str_new(buffer, 20L); 1198 } 1199 1200 /* 1201 * NAME: hash->blocks() 1202 * DESCRIPTION: hash string blocks with a given function 1203 */ 1204 static Uint hash_blocks(frame *f, int nargs, Uint *digest, char *buffer, 1205 unsigned short *bufsize, unsigned int blocksz, 1206 void (*hash_block) (Uint*, char*)) 1207 { 1208 ssizet len; 1209 unsigned short bufsz; 1210 char *p; 1211 Uint length; 1212 1213 length = 0; 1214 bufsz = 0; 1215 while (--nargs >= 0) { 1216 len = f->sp[nargs].u.string->len; 1217 if (len != 0) { 1218 length += len; 1219 p = f->sp[nargs].u.string->text; 1220 if (bufsz != 0) { 1221 unsigned short size; 1222 1223 /* fill buffer and digest */ 1224 size = blocksz - bufsz; 1225 if (size > len) { 1226 size = len; 1227 } 1228 memcpy(buffer + bufsz, p, size); 1229 p += size; 1230 len -= size; 1231 bufsz += size; 1232 1233 if (bufsz == blocksz) { 1234 (*hash_block)(digest, buffer); 1235 bufsz = 0; 1236 } 1237 } 1238 1239 while (len >= blocksz) { 1240 /* digest directly from string */ 1241 (*hash_block)(digest, p); 1242 p += blocksz; 1243 len -= blocksz; 1244 } 1245 1246 if (len != 0) { 1247 /* put remainder in buffer */ 1248 memcpy(buffer, p, bufsz = len); 1249 } 1250 } 1251 } 1252 1253 *bufsize = bufsz; 1254 return length; 1255 } 1256 1257 /* 1258 * NAME: kfun->md5() 1259 * DESCRIPTION: compute MD5 hash 1260 */ 1261 void kf_md5(frame *f, int nargs, value *val) 1262 { 1263 char buffer[64]; 1264 Uint digest[5]; 1265 Int cost; 1266 Uint length; 1267 unsigned short bufsz; 1268 string *str; 1269 1270 cost = hash_md5_start(f, nargs, digest); 1271 if (!f->rlim->noticks && f->rlim->ticks <= cost) { 1272 f->rlim->ticks = 0; 1273 error("Out of ticks"); 1274 } 1275 i_add_ticks(f, cost); 1276 1277 length = hash_blocks(f, nargs, digest, buffer, &bufsz, 64, &hash_md5_block); 1278 str = hash_md5_end(digest, buffer, bufsz, length); 1279 PUT_STRVAL_NOREF(val, str); 1280 } 1281 1282 /* 1283 * NAME: kfun->sha1() 1284 * DESCRIPTION: compute SHA1 hash 1285 */ 1286 void kf_sha1(frame *f, int nargs, value *val) 1287 { 1288 char buffer[64]; 1289 Uint digest[5]; 1290 Int cost; 1291 Uint length; 1292 unsigned short bufsz; 1293 string *str; 1294 1295 cost = hash_sha1_start(f, nargs, digest); 1296 if (!f->rlim->noticks && f->rlim->ticks <= cost) { 1297 f->rlim->ticks = 0; 1298 error("Out of ticks"); 1299 } 1300 i_add_ticks(f, cost); 1301 1302 length = hash_blocks(f, nargs, digest, buffer, &bufsz, 64, 1303 &hash_sha1_block); 1304 str = hash_sha1_end(digest, buffer, bufsz, length); 1305 PUT_STRVAL_NOREF(val, str); 1306 } 1307 # endif 1308 1309 1310 # ifdef FUNCDEF 1311 FUNCDEF("crypt", kf_crypt, pt_crypt, 0) 1312 # else 1313 char pt_crypt[] = { C_TYPECHECKED | C_STATIC, 1, 1, 0, 8, T_STRING, T_STRING, 1314 T_STRING }; 1315 1316 /* 1317 * NAME: kfun->crypt() 1318 * DESCRIPTION: hash_string("crypt", ...) 1319 */ 1320 int kf_crypt(frame *f, int nargs) 1321 { 1322 value val; 1323 1324 kf_xcrypt(f, nargs, &val); 1325 i_ref_value(&val); 1326 i_pop(f, nargs); 1327 *--f->sp = val; 1328 return 0; 1329 } 1330 # endif 1331 1332 1333 # ifdef FUNCDEF 1334 FUNCDEF("0.hash_md5", kf_hash_md5, pt_hash_md5, 0) 1335 # else 1336 char pt_hash_md5[] = { C_TYPECHECKED | C_STATIC | C_ELLIPSIS, 1, 1, 0, 8, 1337 T_STRING, T_STRING, T_STRING }; 1338 1339 /* 1340 * NAME: kfun->hash_md5() 1341 * DESCRIPTION: hash_string("MD5", ...) 1342 */ 1343 int kf_hash_md5(frame *f, int nargs) 1344 { 1345 char buffer[64]; 1346 Uint digest[4]; 1347 Int cost; 1348 Uint length; 1349 unsigned short bufsz; 1350 1351 cost = hash_md5_start(f, nargs, digest); 1352 if (!f->rlim->noticks && f->rlim->ticks <= cost) { 1353 f->rlim->ticks = 0; 1354 error("Out of ticks"); 1355 } 1356 i_add_ticks(f, cost); 1357 1358 length = hash_blocks(f, nargs, digest, buffer, &bufsz, 64, &hash_md5_block); 1359 1360 i_pop(f, nargs); 1361 PUSH_STRVAL(f, hash_md5_end(digest, buffer, bufsz, length)); 1362 return 0; 1363 } 1364 # endif 1365 1366 1367 # ifdef FUNCDEF 1368 FUNCDEF("0.hash_sha1", kf_hash_sha1, pt_hash_sha1, 0) 1369 # else 1370 char pt_hash_sha1[] = { C_TYPECHECKED | C_STATIC | C_ELLIPSIS, 1, 1, 0, 8, 1371 T_STRING, T_STRING, T_STRING }; 1372 1373 /* 1374 * NAME: kfun->hash_sha1() 1375 * DESCRIPTION: hash_string("SHA1", ...) 1376 */ 1377 int kf_hash_sha1(frame *f, int nargs) 1378 { 1379 char buffer[64]; 1380 Uint digest[5]; 1381 Int cost; 1382 Uint length; 1383 unsigned short bufsz; 1384 1385 cost = hash_sha1_start(f, nargs, digest); 1386 if (!f->rlim->noticks && f->rlim->ticks <= cost) { 1387 f->rlim->ticks = 0; 1388 error("Out of ticks"); 1389 } 1390 i_add_ticks(f, cost); 1391 1392 length = hash_blocks(f, nargs, digest, buffer, &bufsz, 64, 1393 &hash_sha1_block); 1394 1395 i_pop(f, nargs); 1396 PUSH_STRVAL(f, hash_sha1_end(digest, buffer, bufsz, length)); 1397 return 0; 1398 } 1399 # endif 1400 1401 1402 # ifdef FUNCDEF 1403 FUNCDEF("asn_add", kf_asn_add, pt_asn_add, 0) 1404 # else 1405 char pt_asn_add[] = { C_TYPECHECKED | C_STATIC, 3, 0, 0, 9, T_STRING, T_STRING, 1406 T_STRING, T_STRING }; 1407 1408 /* 1409 * NAME: kfun->asn_add() 1410 * DESCRIPTION: add two arbitrary precision numbers 1411 */ 1412 int kf_asn_add(frame *f) 1413 { 1414 string *str; 1415 1416 str = asn_add(f, f->sp[2].u.string, f->sp[1].u.string, f->sp[0].u.string); 1417 str_del((f->sp++)->u.string); 1418 str_del((f->sp++)->u.string); 1419 str_del(f->sp->u.string); 1420 PUT_STR(f->sp, str); 1421 1422 return 0; 1423 } 1424 # endif 1425 1426 1427 # ifdef FUNCDEF 1428 FUNCDEF("asn_sub", kf_asn_sub, pt_asn_sub, 0) 1429 # else 1430 char pt_asn_sub[] = { C_TYPECHECKED | C_STATIC, 3, 0, 0, 9, T_STRING, T_STRING, 1431 T_STRING, T_STRING }; 1432 1433 /* 1434 * NAME: kfun->asn_sub() 1435 * DESCRIPTION: subtract arbitrary precision numbers 1436 */ 1437 int kf_asn_sub(frame *f) 1438 { 1439 string *str; 1440 1441 str = asn_sub(f, f->sp[2].u.string, f->sp[1].u.string, f->sp[0].u.string); 1442 str_del((f->sp++)->u.string); 1443 str_del((f->sp++)->u.string); 1444 str_del(f->sp->u.string); 1445 PUT_STR(f->sp, str); 1446 1447 return 0; 1448 } 1449 # endif 1450 1451 1452 # ifdef FUNCDEF 1453 FUNCDEF("asn_cmp", kf_asn_cmp, pt_asn_cmp, 0) 1454 # else 1455 char pt_asn_cmp[] = { C_TYPECHECKED | C_STATIC, 2, 0, 0, 8, T_INT, T_STRING, 1456 T_STRING }; 1457 1458 /* 1459 * NAME: kfun->asn_cmp() 1460 * DESCRIPTION: subtract arbitrary precision numbers 1461 */ 1462 int kf_asn_cmp(frame *f) 1463 { 1464 int cmp; 1465 1466 cmp = asn_cmp(f, f->sp[1].u.string, f->sp[0].u.string); 1467 str_del((f->sp++)->u.string); 1468 str_del(f->sp->u.string); 1469 PUT_INTVAL(f->sp, cmp); 1470 1471 return 0; 1472 } 1473 # endif 1474 1475 1476 # ifdef FUNCDEF 1477 FUNCDEF("asn_mult", kf_asn_mult, pt_asn_mult, 0) 1478 # else 1479 char pt_asn_mult[] = { C_TYPECHECKED | C_STATIC, 3, 0, 0, 9, T_STRING, T_STRING, 1480 T_STRING, T_STRING }; 1481 1482 /* 1483 * NAME: kfun->asn_mult() 1484 * DESCRIPTION: multiply arbitrary precision numbers 1485 */ 1486 int kf_asn_mult(frame *f) 1487 { 1488 string *str; 1489 1490 str = asn_mult(f, f->sp[2].u.string, f->sp[1].u.string, f->sp[0].u.string); 1491 str_del((f->sp++)->u.string); 1492 str_del((f->sp++)->u.string); 1493 str_del(f->sp->u.string); 1494 PUT_STR(f->sp, str); 1495 1496 return 0; 1497 } 1498 # endif 1499 1500 1501 # ifdef FUNCDEF 1502 FUNCDEF("asn_div", kf_asn_div, pt_asn_div, 0) 1503 # else 1504 char pt_asn_div[] = { C_TYPECHECKED | C_STATIC, 3, 0, 0, 9, T_STRING, T_STRING, 1505 T_STRING, T_STRING }; 1506 1507 /* 1508 * NAME: kfun->asn_div() 1509 * DESCRIPTION: divide arbitrary precision numbers 1510 */ 1511 int kf_asn_div(frame *f) 1512 { 1513 string *str; 1514 1515 str = asn_div(f, f->sp[2].u.string, f->sp[1].u.string, f->sp[0].u.string); 1516 str_del((f->sp++)->u.string); 1517 str_del((f->sp++)->u.string); 1518 str_del(f->sp->u.string); 1519 PUT_STR(f->sp, str); 1520 1521 return 0; 1522 } 1523 # endif 1524 1525 1526 # ifdef FUNCDEF 1527 FUNCDEF("asn_mod", kf_asn_mod, pt_asn_mod, 0) 1528 # else 1529 char pt_asn_mod[] = { C_TYPECHECKED | C_STATIC, 2, 0, 0, 8, T_STRING, T_STRING, 1530 T_STRING }; 1531 1532 /* 1533 * NAME: kfun->asn_mod() 1534 * DESCRIPTION: modulus of arbitrary precision number 1535 */ 1536 int kf_asn_mod(frame *f) 1537 { 1538 string *str; 1539 1540 str = asn_mod(f, f->sp[1].u.string, f->sp[0].u.string); 1541 str_del((f->sp++)->u.string); 1542 str_del(f->sp->u.string); 1543 PUT_STR(f->sp, str); 1544 1545 return 0; 1546 } 1547 # endif 1548 1549 1550 # ifdef FUNCDEF 1551 FUNCDEF("asn_pow", kf_asn_pow, pt_asn_pow, 0) 1552 # else 1553 char pt_asn_pow[] = { C_TYPECHECKED | C_STATIC, 3, 0, 0, 9, T_STRING, T_STRING, 1554 T_STRING, T_STRING }; 1555 1556 /* 1557 * NAME: kfun->asn_pow() 1558 * DESCRIPTION: power of an arbitrary precision number 1559 */ 1560 int kf_asn_pow(frame *f) 1561 { 1562 string *str; 1563 1564 str = asn_pow(f, f->sp[2].u.string, f->sp[1].u.string, f->sp[0].u.string); 1565 str_del((f->sp++)->u.string); 1566 str_del((f->sp++)->u.string); 1567 str_del(f->sp->u.string); 1568 PUT_STR(f->sp, str); 1569 1570 return 0; 1571 } 1572 # endif 1573 1574 1575 # ifdef FUNCDEF 1576 FUNCDEF("asn_lshift", kf_asn_lshift, pt_asn_lshift, 0) 1577 # else 1578 char pt_asn_lshift[] = { C_TYPECHECKED | C_STATIC, 3, 0, 0, 9, T_STRING, 1579 T_STRING, T_INT, T_STRING }; 1580 1581 /* 1582 * NAME: kfun->asn_lshift() 1583 * DESCRIPTION: left shift an arbitrary precision number 1584 */ 1585 int kf_asn_lshift(frame *f) 1586 { 1587 string *str; 1588 1589 str = asn_lshift(f, f->sp[2].u.string, f->sp[1].u.number, f->sp->u.string); 1590 str_del(f->sp->u.string); 1591 f->sp += 2; 1592 str_del(f->sp->u.string); 1593 PUT_STR(f->sp, str); 1594 1595 return 0; 1596 } 1597 # endif 1598 1599 1600 # ifdef FUNCDEF 1601 FUNCDEF("asn_rshift", kf_asn_rshift, pt_asn_rshift, 0) 1602 # else 1603 char pt_asn_rshift[] = { C_TYPECHECKED | C_STATIC, 2, 0, 0, 8, T_STRING, 1604 T_STRING, T_INT }; 1605 1606 /* 1607 * NAME: kfun->asn_rshift() 1608 * DESCRIPTION: right shift of arbitrary precision number 1609 */ 1610 int kf_asn_rshift(frame *f) 1611 { 1612 string *str; 1613 1614 str = asn_rshift(f, f->sp[1].u.string, f->sp->u.number); 1615 f->sp++; 1616 str_del(f->sp->u.string); 1617 PUT_STR(f->sp, str); 1618 1619 return 0; 1620 } 1621 # endif 1622 1623 1624 # ifdef FUNCDEF 1625 FUNCDEF("asn_and", kf_asn_and, pt_asn_and, 0) 1626 # else 1627 char pt_asn_and[] = { C_TYPECHECKED | C_STATIC, 2, 0, 0, 8, T_STRING, T_STRING, 1628 T_STRING }; 1629 1630 /* 1631 * NAME: kfun->asn_and() 1632 * DESCRIPTION: logical and of arbitrary precision numbers 1633 */ 1634 int kf_asn_and(frame *f) 1635 { 1636 string *str; 1637 1638 str = asn_and(f, f->sp[1].u.string, f->sp->u.string); 1639 str_del((f->sp++)->u.string); 1640 str_del(f->sp->u.string); 1641 PUT_STR(f->sp, str); 1642 1643 return 0; 1644 } 1645 # endif 1646 1647 1648 # ifdef FUNCDEF 1649 FUNCDEF("asn_or", kf_asn_or, pt_asn_or, 0) 1650 # else 1651 char pt_asn_or[] = { C_TYPECHECKED | C_STATIC, 2, 0, 0, 8, T_STRING, T_STRING, 1652 T_STRING }; 1653 1654 /* 1655 * NAME: kfun->asn_or() 1656 * DESCRIPTION: logical or of arbitrary precision numbers 1657 */ 1658 int kf_asn_or(frame *f) 1659 { 1660 string *str; 1661 1662 str = asn_or(f, f->sp[1].u.string, f->sp->u.string); 1663 str_del((f->sp++)->u.string); 1664 str_del(f->sp->u.string); 1665 PUT_STR(f->sp, str); 1666 1667 return 0; 1668 } 1669 # endif 1670 1671 1672 # ifdef FUNCDEF 1673 FUNCDEF("asn_xor", kf_asn_xor, pt_asn_xor, 0) 1674 # else 1675 char pt_asn_xor[] = { C_TYPECHECKED | C_STATIC, 2, 0, 0, 8, T_STRING, T_STRING, 1676 T_STRING }; 1677 1678 /* 1679 * NAME: kfun->asn_xor() 1680 * DESCRIPTION: logical xor of arbitrary precision numbers 1681 */ 1682 int kf_asn_xor(frame *f) 1683 { 1684 string *str; 1685 1686 str = asn_xor(f, f->sp[1].u.string, f->sp->u.string); 1687 str_del((f->sp++)->u.string); 1688 str_del(f->sp->u.string); 1689 PUT_STR(f->sp, str); 1690 1691 return 0; 1692 } 1693 # endif 1694