fips_desmovs.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625
  1. /* ====================================================================
  2. * Copyright (c) 2004 The OpenSSL Project. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. *
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in
  13. * the documentation and/or other materials provided with the
  14. * distribution.
  15. *
  16. * 3. All advertising materials mentioning features or use of this
  17. * software must display the following acknowledgment:
  18. * "This product includes software developed by the OpenSSL Project
  19. * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
  20. *
  21. * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
  22. * endorse or promote products derived from this software without
  23. * prior written permission. For written permission, please contact
  24. * openssl-core@openssl.org.
  25. *
  26. * 5. Products derived from this software may not be called "OpenSSL"
  27. * nor may "OpenSSL" appear in their names without prior written
  28. * permission of the OpenSSL Project.
  29. *
  30. * 6. Redistributions of any form whatsoever must retain the following
  31. * acknowledgment:
  32. * "This product includes software developed by the OpenSSL Project
  33. * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
  34. *
  35. * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
  36. * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  37. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  38. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
  39. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  41. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  42. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  43. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  44. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  45. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  46. * OF THE POSSIBILITY OF SUCH DAMAGE.
  47. *
  48. */
  49. /* --------------------------------------------
  50. NIST DES Modes of Operation Validation System
  51. Test Program
  52. Based on the AES Validation Suite, which was:
  53. Donated to OpenSSL by:
  54. V-ONE Corporation
  55. 20250 Century Blvd, Suite 300
  56. Germantown, MD 20874
  57. U.S.A.
  58. ----------------------------------------------*/
  59. #include <stdio.h>
  60. #include <stdlib.h>
  61. #include <string.h>
  62. #include <errno.h>
  63. #include <assert.h>
  64. #include <ctype.h>
  65. #include <openssl/des.h>
  66. #include <openssl/evp.h>
  67. #include <openssl/bn.h>
  68. #include <openssl/err.h>
  69. #include "e_os.h"
  70. #ifndef OPENSSL_FIPS
  71. int main(int argc, char *argv[])
  72. {
  73. printf("No FIPS DES support\n");
  74. return (0);
  75. }
  76. #else
  77. # include <openssl/fips.h>
  78. # include "fips_utl.h"
  79. # define DES_BLOCK_SIZE 8
  80. # define VERBOSE 0
  81. static int DESTest(EVP_CIPHER_CTX *ctx,
  82. char *amode, int akeysz, unsigned char *aKey,
  83. unsigned char *iVec,
  84. /* 0 = decrypt, 1 = encrypt */
  85. int dir, unsigned char *out, unsigned char *in, int len)
  86. {
  87. const EVP_CIPHER *cipher = NULL;
  88. if (akeysz != 192) {
  89. printf("Invalid key size: %d\n", akeysz);
  90. EXIT(1);
  91. }
  92. if (strcasecmp(amode, "CBC") == 0)
  93. cipher = EVP_des_ede3_cbc();
  94. else if (strcasecmp(amode, "ECB") == 0)
  95. cipher = EVP_des_ede3_ecb();
  96. else if (strcasecmp(amode, "CFB64") == 0)
  97. cipher = EVP_des_ede3_cfb64();
  98. else if (strncasecmp(amode, "OFB", 3) == 0)
  99. cipher = EVP_des_ede3_ofb();
  100. else if (!strcasecmp(amode, "CFB8"))
  101. cipher = EVP_des_ede3_cfb8();
  102. else if (!strcasecmp(amode, "CFB1"))
  103. cipher = EVP_des_ede3_cfb1();
  104. else {
  105. printf("Unknown mode: %s\n", amode);
  106. EXIT(1);
  107. }
  108. if (EVP_CipherInit_ex(ctx, cipher, NULL, aKey, iVec, dir) <= 0)
  109. return 0;
  110. if (!strcasecmp(amode, "CFB1"))
  111. M_EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS);
  112. EVP_Cipher(ctx, out, in, len);
  113. return 1;
  114. }
  115. # if 0
  116. static void DebugValue(char *tag, unsigned char *val, int len)
  117. {
  118. char obuf[2048];
  119. int olen;
  120. olen = bin2hex(val, len, obuf);
  121. printf("%s = %.*s\n", tag, olen, obuf);
  122. }
  123. # endif
  124. static void shiftin(unsigned char *dst, unsigned char *src, int nbits)
  125. {
  126. int n;
  127. /* move the bytes... */
  128. memmove(dst, dst + nbits / 8, 3 * 8 - nbits / 8);
  129. /* append new data */
  130. memcpy(dst + 3 * 8 - nbits / 8, src, (nbits + 7) / 8);
  131. /* left shift the bits */
  132. if (nbits % 8)
  133. for (n = 0; n < 3 * 8; ++n)
  134. dst[n] =
  135. (dst[n] << (nbits % 8)) | (dst[n + 1] >> (8 - nbits % 8));
  136. }
  137. /* ---------------------------------------------*/
  138. char *t_tag[2] = { "PLAINTEXT", "CIPHERTEXT" };
  139. char *t_mode[6] = { "CBC", "ECB", "OFB", "CFB1", "CFB8", "CFB64" };
  140. enum Mode { CBC, ECB, OFB, CFB1, CFB8, CFB64 };
  141. int Sizes[6] = { 64, 64, 64, 1, 8, 64 };
  142. static void do_mct(char *amode,
  143. int akeysz, int numkeys, unsigned char *akey,
  144. unsigned char *ivec, int dir, unsigned char *text, int len,
  145. FILE *rfp)
  146. {
  147. int i, imode;
  148. unsigned char nk[4 * 8]; /* longest key+8 */
  149. unsigned char text0[8];
  150. for (imode = 0; imode < 6; ++imode)
  151. if (!strcmp(amode, t_mode[imode]))
  152. break;
  153. if (imode == 6) {
  154. printf("Unrecognized mode: %s\n", amode);
  155. EXIT(1);
  156. }
  157. for (i = 0; i < 400; ++i) {
  158. int j;
  159. int n;
  160. int kp = akeysz / 64;
  161. unsigned char old_iv[8];
  162. EVP_CIPHER_CTX ctx;
  163. EVP_CIPHER_CTX_init(&ctx);
  164. fprintf(rfp, "\nCOUNT = %d\n", i);
  165. if (kp == 1)
  166. OutputValue("KEY", akey, 8, rfp, 0);
  167. else
  168. for (n = 0; n < kp; ++n) {
  169. fprintf(rfp, "KEY%d", n + 1);
  170. OutputValue("", akey + n * 8, 8, rfp, 0);
  171. }
  172. if (imode != ECB)
  173. OutputValue("IV", ivec, 8, rfp, 0);
  174. OutputValue(t_tag[dir ^ 1], text, len, rfp, imode == CFB1);
  175. # if 0
  176. /* compensate for endianness */
  177. if (imode == CFB1)
  178. text[0] <<= 7;
  179. # endif
  180. memcpy(text0, text, 8);
  181. for (j = 0; j < 10000; ++j) {
  182. unsigned char old_text[8];
  183. memcpy(old_text, text, 8);
  184. if (j == 0) {
  185. memcpy(old_iv, ivec, 8);
  186. DESTest(&ctx, amode, akeysz, akey, ivec, dir, text, text,
  187. len);
  188. } else {
  189. memcpy(old_iv, ctx.iv, 8);
  190. EVP_Cipher(&ctx, text, text, len);
  191. }
  192. if (j == 9999) {
  193. OutputValue(t_tag[dir], text, len, rfp, imode == CFB1);
  194. /* memcpy(ivec,text,8); */
  195. }
  196. /* DebugValue("iv",ctx.iv,8); */
  197. /* accumulate material for the next key */
  198. shiftin(nk, text, Sizes[imode]);
  199. /* DebugValue("nk",nk,24); */
  200. if ((dir && (imode == CFB1 || imode == CFB8 || imode == CFB64
  201. || imode == CBC)) || imode == OFB)
  202. memcpy(text, old_iv, 8);
  203. if (!dir && (imode == CFB1 || imode == CFB8 || imode == CFB64)) {
  204. /*
  205. * the test specifies using the output of the raw DES
  206. * operation which we don't have, so reconstruct it...
  207. */
  208. for (n = 0; n < 8; ++n)
  209. text[n] ^= old_text[n];
  210. }
  211. }
  212. for (n = 0; n < 8; ++n)
  213. akey[n] ^= nk[16 + n];
  214. for (n = 0; n < 8; ++n)
  215. akey[8 + n] ^= nk[8 + n];
  216. for (n = 0; n < 8; ++n)
  217. akey[16 + n] ^= nk[n];
  218. if (numkeys < 3)
  219. memcpy(&akey[2 * 8], akey, 8);
  220. if (numkeys < 2)
  221. memcpy(&akey[8], akey, 8);
  222. DES_set_odd_parity((DES_cblock *)akey);
  223. DES_set_odd_parity((DES_cblock *)(akey + 8));
  224. DES_set_odd_parity((DES_cblock *)(akey + 16));
  225. memcpy(ivec, ctx.iv, 8);
  226. /*
  227. * pointless exercise - the final text doesn't depend on the initial
  228. * text in OFB mode, so who cares what it is? (Who designed these
  229. * tests?)
  230. */
  231. if (imode == OFB)
  232. for (n = 0; n < 8; ++n)
  233. text[n] = text0[n] ^ old_iv[n];
  234. }
  235. }
  236. static int proc_file(char *rqfile, char *rspfile)
  237. {
  238. char afn[256], rfn[256];
  239. FILE *afp = NULL, *rfp = NULL;
  240. char ibuf[2048], tbuf[2048];
  241. int ilen, len, ret = 0;
  242. char amode[8] = "";
  243. char atest[100] = "";
  244. int akeysz = 0;
  245. unsigned char iVec[20], aKey[40];
  246. int dir = -1, err = 0, step = 0;
  247. unsigned char plaintext[2048];
  248. unsigned char ciphertext[2048];
  249. char *rp;
  250. EVP_CIPHER_CTX ctx;
  251. int numkeys = 1;
  252. EVP_CIPHER_CTX_init(&ctx);
  253. if (!rqfile || !(*rqfile)) {
  254. printf("No req file\n");
  255. return -1;
  256. }
  257. strcpy(afn, rqfile);
  258. if ((afp = fopen(afn, "r")) == NULL) {
  259. printf("Cannot open file: %s, %s\n", afn, strerror(errno));
  260. return -1;
  261. }
  262. if (!rspfile) {
  263. strcpy(rfn, afn);
  264. rp = strstr(rfn, "req/");
  265. # ifdef OPENSSL_SYS_WIN32
  266. if (!rp)
  267. rp = strstr(rfn, "req\\");
  268. # endif
  269. assert(rp);
  270. memcpy(rp, "rsp", 3);
  271. rp = strstr(rfn, ".req");
  272. memcpy(rp, ".rsp", 4);
  273. rspfile = rfn;
  274. }
  275. if ((rfp = fopen(rspfile, "w")) == NULL) {
  276. printf("Cannot open file: %s, %s\n", rfn, strerror(errno));
  277. fclose(afp);
  278. afp = NULL;
  279. return -1;
  280. }
  281. while (!err && (fgets(ibuf, sizeof(ibuf), afp)) != NULL) {
  282. tidy_line(tbuf, ibuf);
  283. ilen = strlen(ibuf);
  284. /* printf("step=%d ibuf=%s",step,ibuf); */
  285. if (step == 3 && !strcmp(amode, "ECB")) {
  286. memset(iVec, 0, sizeof(iVec));
  287. step = (dir) ? 4 : 5; /* no ivec for ECB */
  288. }
  289. switch (step) {
  290. case 0: /* read preamble */
  291. if (ibuf[0] == '\n') { /* end of preamble */
  292. if (*amode == '\0') {
  293. printf("Missing Mode\n");
  294. err = 1;
  295. } else {
  296. fputs(ibuf, rfp);
  297. ++step;
  298. }
  299. } else if (ibuf[0] != '#') {
  300. printf("Invalid preamble item: %s\n", ibuf);
  301. err = 1;
  302. } else { /* process preamble */
  303. char *xp, *pp = ibuf + 2;
  304. int n;
  305. if (*amode) { /* insert current time & date */
  306. time_t rtim = time(0);
  307. fprintf(rfp, "# %s", ctime(&rtim));
  308. } else {
  309. fputs(ibuf, rfp);
  310. if (!strncmp(pp, "INVERSE ", 8) || !strncmp(pp, "DES ", 4)
  311. || !strncmp(pp, "TDES ", 5)
  312. || !strncmp(pp, "PERMUTATION ", 12)
  313. || !strncmp(pp, "SUBSTITUTION ", 13)
  314. || !strncmp(pp, "VARIABLE ", 9)) {
  315. /* get test type */
  316. if (!strncmp(pp, "DES ", 4))
  317. pp += 4;
  318. else if (!strncmp(pp, "TDES ", 5))
  319. pp += 5;
  320. xp = strchr(pp, ' ');
  321. n = xp - pp;
  322. strncpy(atest, pp, n);
  323. atest[n] = '\0';
  324. /* get mode */
  325. xp = strrchr(pp, ' '); /* get mode" */
  326. n = strlen(xp + 1) - 1;
  327. strncpy(amode, xp + 1, n);
  328. amode[n] = '\0';
  329. /* amode[3] = '\0'; */
  330. if (VERBOSE)
  331. printf("Test=%s, Mode=%s\n", atest, amode);
  332. }
  333. }
  334. }
  335. break;
  336. case 1: /* [ENCRYPT] | [DECRYPT] */
  337. if (ibuf[0] == '\n')
  338. break;
  339. if (ibuf[0] == '[') {
  340. fputs(ibuf, rfp);
  341. ++step;
  342. if (strncasecmp(ibuf, "[ENCRYPT]", 9) == 0)
  343. dir = 1;
  344. else if (strncasecmp(ibuf, "[DECRYPT]", 9) == 0)
  345. dir = 0;
  346. else {
  347. printf("Invalid keyword: %s\n", ibuf);
  348. err = 1;
  349. }
  350. break;
  351. } else if (dir == -1) {
  352. err = 1;
  353. printf("Missing ENCRYPT/DECRYPT keyword\n");
  354. break;
  355. } else
  356. step = 2;
  357. case 2: /* KEY = xxxx */
  358. if (*ibuf == '\n') {
  359. fputs(ibuf, rfp);
  360. break;
  361. }
  362. if (!strncasecmp(ibuf, "COUNT = ", 8)) {
  363. fputs(ibuf, rfp);
  364. break;
  365. }
  366. if (!strncasecmp(ibuf, "COUNT=", 6)) {
  367. fputs(ibuf, rfp);
  368. break;
  369. }
  370. if (!strncasecmp(ibuf, "NumKeys = ", 10)) {
  371. numkeys = atoi(ibuf + 10);
  372. break;
  373. }
  374. fputs(ibuf, rfp);
  375. if (!strncasecmp(ibuf, "KEY = ", 6)) {
  376. akeysz = 64;
  377. len = hex2bin((char *)ibuf + 6, aKey);
  378. if (len < 0) {
  379. printf("Invalid KEY\n");
  380. err = 1;
  381. break;
  382. }
  383. PrintValue("KEY", aKey, len);
  384. ++step;
  385. } else if (!strncasecmp(ibuf, "KEYs = ", 7)) {
  386. akeysz = 64 * 3;
  387. len = hex2bin(ibuf + 7, aKey);
  388. if (len != 8) {
  389. printf("Invalid KEY\n");
  390. err = 1;
  391. break;
  392. }
  393. memcpy(aKey + 8, aKey, 8);
  394. memcpy(aKey + 16, aKey, 8);
  395. ibuf[4] = '\0';
  396. PrintValue("KEYs", aKey, len);
  397. ++step;
  398. } else if (!strncasecmp(ibuf, "KEY", 3)) {
  399. int n = ibuf[3] - '1';
  400. akeysz = 64 * 3;
  401. len = hex2bin(ibuf + 7, aKey + n * 8);
  402. if (len != 8) {
  403. printf("Invalid KEY\n");
  404. err = 1;
  405. break;
  406. }
  407. ibuf[4] = '\0';
  408. PrintValue(ibuf, aKey, len);
  409. if (n == 2)
  410. ++step;
  411. } else {
  412. printf("Missing KEY\n");
  413. err = 1;
  414. }
  415. break;
  416. case 3: /* IV = xxxx */
  417. fputs(ibuf, rfp);
  418. if (strncasecmp(ibuf, "IV = ", 5) != 0) {
  419. printf("Missing IV\n");
  420. err = 1;
  421. } else {
  422. len = hex2bin((char *)ibuf + 5, iVec);
  423. if (len < 0) {
  424. printf("Invalid IV\n");
  425. err = 1;
  426. break;
  427. }
  428. PrintValue("IV", iVec, len);
  429. step = (dir) ? 4 : 5;
  430. }
  431. break;
  432. case 4: /* PLAINTEXT = xxxx */
  433. fputs(ibuf, rfp);
  434. if (strncasecmp(ibuf, "PLAINTEXT = ", 12) != 0) {
  435. printf("Missing PLAINTEXT\n");
  436. err = 1;
  437. } else {
  438. int nn = strlen(ibuf + 12);
  439. if (!strcmp(amode, "CFB1"))
  440. len = bint2bin(ibuf + 12, nn - 1, plaintext);
  441. else
  442. len = hex2bin(ibuf + 12, plaintext);
  443. if (len < 0) {
  444. printf("Invalid PLAINTEXT: %s", ibuf + 12);
  445. err = 1;
  446. break;
  447. }
  448. if (len >= (int)sizeof(plaintext)) {
  449. printf("Buffer overflow\n");
  450. }
  451. PrintValue("PLAINTEXT", (unsigned char *)plaintext, len);
  452. if (strcmp(atest, "Monte") == 0) { /* Monte Carlo Test */
  453. do_mct(amode, akeysz, numkeys, aKey, iVec, dir, plaintext,
  454. len, rfp);
  455. } else {
  456. assert(dir == 1);
  457. ret = DESTest(&ctx, amode, akeysz, aKey, iVec,
  458. /* 0 = decrypt, 1 = encrypt */
  459. dir, ciphertext, plaintext, len);
  460. OutputValue("CIPHERTEXT", ciphertext, len, rfp,
  461. !strcmp(amode, "CFB1"));
  462. }
  463. step = 6;
  464. }
  465. break;
  466. case 5: /* CIPHERTEXT = xxxx */
  467. fputs(ibuf, rfp);
  468. if (strncasecmp(ibuf, "CIPHERTEXT = ", 13) != 0) {
  469. printf("Missing KEY\n");
  470. err = 1;
  471. } else {
  472. if (!strcmp(amode, "CFB1"))
  473. len =
  474. bint2bin(ibuf + 13, strlen(ibuf + 13) - 1,
  475. ciphertext);
  476. else
  477. len = hex2bin(ibuf + 13, ciphertext);
  478. if (len < 0) {
  479. printf("Invalid CIPHERTEXT\n");
  480. err = 1;
  481. break;
  482. }
  483. PrintValue("CIPHERTEXT", ciphertext, len);
  484. if (strcmp(atest, "Monte") == 0) { /* Monte Carlo Test */
  485. do_mct(amode, akeysz, numkeys, aKey, iVec,
  486. dir, ciphertext, len, rfp);
  487. } else {
  488. assert(dir == 0);
  489. ret = DESTest(&ctx, amode, akeysz, aKey, iVec,
  490. /* 0 = decrypt, 1 = encrypt */
  491. dir, plaintext, ciphertext, len);
  492. OutputValue("PLAINTEXT", (unsigned char *)plaintext, len,
  493. rfp, !strcmp(amode, "CFB1"));
  494. }
  495. step = 6;
  496. }
  497. break;
  498. case 6:
  499. if (ibuf[0] != '\n') {
  500. err = 1;
  501. printf("Missing terminator\n");
  502. } else if (strcmp(atest, "MCT") != 0) { /* MCT already added
  503. * terminating nl */
  504. fputs(ibuf, rfp);
  505. }
  506. step = 1;
  507. break;
  508. }
  509. }
  510. if (rfp)
  511. fclose(rfp);
  512. if (afp)
  513. fclose(afp);
  514. return err;
  515. }
  516. /* -------------------------------------------------
  517. Processes either a single file or
  518. a set of files whose names are passed in a file.
  519. A single file is specified as:
  520. aes_test -f xxx.req
  521. A set of files is specified as:
  522. aes_test -d xxxxx.xxx
  523. The default is: -d req.txt
  524. --------------------------------------------------*/
  525. int main(int argc, char **argv)
  526. {
  527. char *rqlist = "req.txt", *rspfile = NULL;
  528. FILE *fp = NULL;
  529. char fn[250] = "", rfn[256] = "";
  530. int f_opt = 0, d_opt = 1;
  531. # ifdef OPENSSL_FIPS
  532. if (!FIPS_mode_set(1)) {
  533. do_print_errors();
  534. EXIT(1);
  535. }
  536. # endif
  537. if (argc > 1) {
  538. if (strcasecmp(argv[1], "-d") == 0) {
  539. d_opt = 1;
  540. } else if (strcasecmp(argv[1], "-f") == 0) {
  541. f_opt = 1;
  542. d_opt = 0;
  543. } else {
  544. printf("Invalid parameter: %s\n", argv[1]);
  545. return 0;
  546. }
  547. if (argc < 3) {
  548. printf("Missing parameter\n");
  549. return 0;
  550. }
  551. if (d_opt)
  552. rqlist = argv[2];
  553. else {
  554. strcpy(fn, argv[2]);
  555. rspfile = argv[3];
  556. }
  557. }
  558. if (d_opt) { /* list of files (directory) */
  559. if (!(fp = fopen(rqlist, "r"))) {
  560. printf("Cannot open req list file\n");
  561. return -1;
  562. }
  563. while (fgets(fn, sizeof(fn), fp)) {
  564. strtok(fn, "\r\n");
  565. strcpy(rfn, fn);
  566. printf("Processing: %s\n", rfn);
  567. if (proc_file(rfn, rspfile)) {
  568. printf(">>> Processing failed for: %s <<<\n", rfn);
  569. EXIT(1);
  570. }
  571. }
  572. fclose(fp);
  573. } else { /* single file */
  574. if (VERBOSE)
  575. printf("Processing: %s\n", fn);
  576. if (proc_file(fn, rspfile)) {
  577. printf(">>> Processing failed for: %s <<<\n", fn);
  578. }
  579. }
  580. EXIT(0);
  581. return 0;
  582. }
  583. #endif