RFC 4634 - US Secure Hash Algorithms (SHA and HMAC-SHA)(8)

时间:2006-11-02 来源: 作者: 点击:
if(printResults==PRINTTEXT) printf("\nError%d.Shouldbe%d.\n",err,shaNull); if((printPassFail==PRINTPASSFAIL)|| ((printPassFail==PRINTFAIL)(err!=shaNull))) printf("%sshanull:%s\n",hashes[hashno].name,
  
    if (printResults == PRINTTEXT)
       printf("\nError %d. Should be %d.\n", err, shaNull);
    if ((printPassFail == PRINTPASSFAIL) ||
        ((printPassFail == PRINTFAIL) && (err != shaNull)))
       printf("%s sha null: %s\n", hashes[hashno].name,
        (err == shaNull) ? "PASSED" : "FAILED");
  }
}

/* replace a hex string in place with its value */
int unhexStr(char *hexstr)
{
  char *o = hexstr;
  int len = 0, nibble1 = 0, nibble2 = 0;
  if (!hexstr) return 0;
  for ( ; *hexstr; hexstr++) {
    if (isalpha((int)(unsigned char)(*hexstr))) {
      nibble1 = tolower(*hexstr) - ’a’ + 10;
    } else if (isdigit((int)(unsigned char)(*hexstr))) {
      nibble1 = *hexstr - ’0’;
    } else {
      printf("\nError: bad hex character ’%c’\n", *hexstr);
    }
    if (!*++hexstr) break;
    if (isalpha((int)(unsigned char)(*hexstr))) {
      nibble2 = tolower(*hexstr) - ’a’ + 10;
    } else if (isdigit((int)(unsigned char)(*hexstr))) {
      nibble2 = *hexstr - ’0’;
    } else {
      printf("\nError: bad hex character ’%c’\n", *hexstr);

    }
    *o++ = (char)((nibble1 << 4) | nibble2);
    len++;
  }
  return len;
}

int main(int argc, char **argv)
{
  int i, err;
  int loopno, loopnohigh = 1;
  int hashno, hashnolow = 0, hashnohigh = HASHCOUNT - 1;
  int testno, testnolow = 0, testnohigh;
  int ntestnohigh = 0;
  int printResults = PRINTTEXT;
  int printPassFail = 1;
  int checkErrors = 0;
  char *hashstr = 0;
  int hashlen = 0;
  const char *resultstr = 0;
  char *randomseedstr = 0;
  int runHmacTests = 0;
  char *hmacKey = 0;
  int hmaclen = 0;
  int randomcount = RANDOMCOUNT;
  const char *hashfilename = 0;
  const char *hashFilename = 0;
  int extrabits = 0, numberExtrabits = 0;
  int strIsHex = 0;

  while ((i = xgetopt(argc, argv, "b:B:ef:F:h:Hk:l:mpPr:R:s:S:t:wxX"))
         != -1)
    switch (i) {
      case ’b’: extrabits = strtol(xoptarg, 0, 0); break;
      case ’B’: numberExtrabits = atoi(xoptarg); break;
      case ’e’: checkErrors = 1; break;
      case ’f’: hashfilename = xoptarg; break;
      case ’F’: hashFilename = xoptarg; break;
      case ’h’: hashnolow = hashnohigh = findhash(argv[0], xoptarg);
        break;
      case ’H’: strIsHex = 1; break;
      case ’k’: hmacKey = xoptarg; hmaclen = strlen(xoptarg); break;
      case ’l’: loopnohigh = atoi(xoptarg); break;
      case ’m’: runHmacTests = 1; break;
      case ’P’: printPassFail = 0; break;
      case ’p’: printResults = PRINTNONE; break;
      case ’R’: randomcount = atoi(xoptarg); break;
      case ’r’: randomseedstr = xoptarg; break;

      case ’s’: hashstr = xoptarg; hashlen = strlen(hashstr); break;
      case ’S’: resultstr = xoptarg; break;
      case ’t’: testnolow = ntestnohigh = atoi(xoptarg) - 1; break;
      case ’w’: printResults = PRINTRAW; break;
      case ’x’: printResults = PRINTHEX; break;
      case ’X’: printPassFail = 2; break;
      default: usage(argv[0]);
      }

  if (strIsHex) {
    hashlen = unhexStr(hashstr);
    unhexStr(randomseedstr);
    hmaclen = unhexStr(hmacKey);
  }
  testnohigh = (ntestnohigh != 0) ? ntestnohigh:
               runHmacTests ? (HMACTESTCOUNT-1) : (TESTCOUNT-1);
  if ((testnolow < 0) ||
      (testnohigh >= (runHmacTests ? HMACTESTCOUNT : TESTCOUNT)) ||
      (hashnolow < 0) || (hashnohigh >= HASHCOUNT) ||
      (hashstr && (testnolow == testnohigh)) ||
      (randomcount < 0) ||
      (resultstr && (!hashstr && !hashfilename && !hashFilename)) ||
      ((runHmacTests || hmacKey) && randomseedstr) ||
      (hashfilename && hashFilename))
    usage(argv[0]);

  /*
   *  Perform SHA/HMAC tests
   */
  for (hashno = hashnolow; hashno <= hashnohigh; ++hashno) {
    if (printResults == PRINTTEXT)
      printf("Hash %s\n", hashes[hashno].name);
    err = shaSuccess;

    for (loopno = 1; (loopno <= loopnohigh) && (err == shaSuccess);
         ++loopno) {
      if (hashstr)
        err = hash(0, loopno, hashno, hashstr, hashlen, 1,
          numberExtrabits, extrabits, (const unsigned char *)hmacKey,
          hmaclen, resultstr, hashes[hashno].hashsize, printResults,
          printPassFail);

      else if (randomseedstr)
        randomtest(hashno, randomseedstr, hashes[hashno].hashsize, 0,
          randomcount, printResults, printPassFail);

      else if (hashfilename)
        err = hashfile(hashno, hashfilename, extrabits,

                       numberExtrabits, 0,
                       (const unsigned char *)hmacKey, hmaclen,
                       resultstr, hashes[hashno].hashsize,
                       printResults, printPassFail);

      else if (hashFilename)
        err = hashfile(hashno, hashFilename, extrabits,
                       numberExtrabits, 1,
                       (const unsigned char *)hmacKey, hmaclen,
                       resultstr, hashes[hashno].hashsize,
                       printResults, printPassFail);

      else /* standard tests */ {
        for (testno = testnolow;
             (testno <= testnohigh) && (err == shaSuccess); ++testno) {
          if (runHmacTests) {
            err = hash(testno, loopno, hashno,
                       hmachashes[testno].dataarray[hashno] ?
                       hmachashes[testno].dataarray[hashno] :
                       hmachashes[testno].dataarray[1] ?
                       hmachashes[testno].dataarray[1] :
                       hmachashes[testno].dataarray[0],
                       hmachashes[testno].datalength[hashno] ?
                       hmachashes[testno].datalength[hashno] :
                       hmachashes[testno].datalength[1] ?
                       hmachashes[testno].datalength[1] :
                       hmachashes[testno].datalength[0],
                       1, 0, 0,
                       (const unsigned char *)(
                        hmachashes[testno].keyarray[hashno] ?
                        hmachashes[testno].keyarray[hashno] :
                        hmachashes[testno].keyarray[1] ?
                        hmachashes[testno].keyarray[1] :
                        hmachashes[testno].keyarray[0]),
                       hmachashes[testno].keylength[hashno] ?
                       hmachashes[testno].keylength[hashno] :
                       hmachashes[testno].keylength[1] ?
                       hmachashes[testno].keylength[1] :
                       hmachashes[testno].keylength[0],
                       hmachashes[testno].resultarray[hashno],
                       hmachashes[testno].resultlength[hashno],
                       printResults, printPassFail);
          } else {
            err = hash(testno, loopno, hashno,
                       hashes[hashno].tests[testno].testarray,
                       hashes[hashno].tests[testno].length,
                       hashes[hashno].tests[testno].repeatcount,
                       hashes[hashno].tests[testno].numberExtrabits,

                       hashes[hashno].tests[testno].extrabits, 0, 0,
                       hashes[hashno].tests[testno].resultarray,
                       hashes[hashno].hashsize,
                       printResults, printPassFail);
          }
        }

        if (!runHmacTests) {
          randomtest(hashno, hashes[hashno].randomtest,
            hashes[hashno].hashsize, hashes[hashno].randomresults,
            RANDOMCOUNT, printResults, printPassFail);
        }
      }
    }
  }

  /* Test some error returns */
  if (checkErrors) {
    testErrors(hashnolow, hashnohigh, printResults, printPassFail);
  }

  return 0;
}

/*
 * Compare two strings, case independently.
 * Equivalent to strcasecmp() found on some systems.
 */
int scasecmp(const char *s1, const char *s2)
{
  for (;;) {
    char u1 = tolower(*s1++);
    char u2 = tolower(*s2++);
    if (u1 != u2)
      return u1 - u2;
    if (u1 == ’\0’)
      return 0;
   }
}

/*
 * This is a copy of getopt provided for those systems that do not
 * have it. The name was changed to xgetopt to not conflict on those
 * systems that do have it. Similarly, optarg, optind and opterr
 * were renamed to xoptarg, xoptind and xopterr.
 *
 * Copyright 1990, 1991, 1992 by the Massachusetts Institute of
 * Technology and UniSoft Group Limited.

 *
 * Permission to use, copy, modify, distribute, and sell this software
 * and its documentation for any purpose is hereby granted without fee,
 * provided that the above copyright notice appear in all copies and
 * that both that copyright notice and this permission notice appear in
 * supporting documentation, and that the names of MIT and UniSoft not
 * be used in advertising or publicity pertaining to distribution of
 * the software without specific, written prior permission.  MIT and
 * UniSoft make no representations about the suitability of this
 * software for any purpose.  It is provided "as is" without express
 * or implied warranty.
 *
 * $XConsortium: getopt.c,v 1.2 92/07/01 11:59:04 rws Exp $
 * NB: Reformatted to match above style.
 */

char    *xoptarg;
int     xoptind = 1;
int     xopterr = 1;

static int xgetopt(int argc, char **argv, const char *optstring)
{
  static int avplace;
  char    *ap;
  char    *cp;
  int     c;

  if (xoptind >= argc)
    return EOF;

  ap = argv[xoptind] + avplace;

  /* At beginning of arg but not an option */
  if (avplace == 0) {
    if (ap[0] != ’-’)
      return EOF;
    else if (ap[1] == ’-’) {
      /* Special end of options option */
      xoptind++;
      return EOF;
    } else if (ap[1] == ’\0’)
      return EOF;  /* single ’-’ is not allowed */
  }

  /* Get next letter */
  avplace++;
  c = *++ap;

  cp = strchr(optstring, c);
  if (cp == NULL || c == ’:’) {
    if (xopterr)
      fprintf(stderr, "Unrecognised option -- %c\n", c);
    return ’?’;
  }

  if (cp[1] == ’:’) {
    /* There should be an option arg */
    avplace = 0;
    if (ap[1] == ’\0’) {
      /* It is a separate arg */
      if (++xoptind >= argc) {
        if (xopterr)
          fprintf(stderr, "Option requires an argument\n");
        return ’?’;
      }
      xoptarg = argv[xoptind++];
    } else {
      /* is attached to option letter */
      xoptarg = ap + 1;
      ++xoptind;
    }
  } else {
    /* If we are out of letters then go to next arg */
    if (ap[1] == ’\0’) {
      ++xoptind;
      avplace = 0;
    }

    xoptarg = NULL;
  }
  return c;
}

9.  Security Considerations

   This document is intended to provides the Internet community
   convenient access to source code that implements the United States of
   America Federal Information Processing Standard Secure Hash
   Algorithms (SHAs) [FIPS180-2] and HMACs based upon these one-way hash
   functions.  See license in Section 1.1.  No independent assertion of
   the security of this hash function by the authors for any particular
   use is intended.

10.  Normative References

   [FIPS180-2] "Secure Hash Standard", United States of America,
               National Institute of Standards and Technology, Federal
               Information Processing Standard (FIPS) 180-2,
               http://csrc.nist.gov/publications/fips/fips180-2/
               fips180-2withchangenotice.pdf.

   [RFC2104]   Krawczyk, H., Bellare, M., and R. Canetti, "HMAC: Keyed-
               Hashing for Message Authentication", RFC 2104, February
               1997.

11.  Informative References

   [RFC2202]   Cheng, P. and R. Glenn, "Test Cases for HMAC-MD5 and
               HMAC-SHA-1", RFC 2202, September 1997.

   [RFC3174]   Eastlake 3rd, D. and P. Jones, "US Secure Hash Algorithm
               1 (SHA1)", RFC 3174, September 2001.

   [RFC3874]   Housley, R., "A 224-bit One-way Hash Function: SHA-224",
               RFC 3874, September 2004.

   [RFC4086]   Eastlake, D., 3rd, Schiller, J., and S. Crocker,
               "Randomness Requirements for Security", BCP 106, RFC
               4086, June 2005.

   [RFC4231]   Nystrom, M., "Identifiers and Test Vectors for HMAC-SHA-
               224, HMAC-SHA-256, HMAC-SHA-384, and HMAC-SHA-512", RFC
               4231, December 2005.

   [SHAVS]     "The Secure Hash Algorithm Validation System (SHAVS)",
               http://csrc.nist.gov/cryptval/shs/SHAVS.pdf.

Authors’ Addresses

   Donald E. Eastlake, 3rd
   Motorola Laboratories
   155 Beaver Street
   Milford, MA 01757 USA

   Phone: +1-508-786-7554 (w)
   EMail: donald.eastlake@motorola.com

   Tony Hansen
   AT&T Laboratories
   200 Laurel Ave.
   Middletown, NJ 07748 USA

   Phone: +1-732-420-8934 (w)
   EMail: tony+shs@maillennium.att.com

Full Copyright Statement

   Copyright (C) The Internet Society (2006).

   This document is subject to the rights, licenses and restrictions
   contained in BCP 78, and except as set forth therein, the authors
   retain all their rights.

   This document and the information contained herein are provided on an
   "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
   OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET
   ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED,
   INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE
   INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

Intellectual Property

   The IETF takes no position regarding the validity or scope of any
   Intellectual Property Rights or other rights that might be claimed to
   pertain to the implementation or use of the technology described in
   this document or the extent to which any license under such rights
   might or might not be available; nor does it represent that it has
   made any independent effort to identify any such rights.  Information
   on the procedures with respect to rights in RFC documents can be
   found in BCP 78 and BCP 79.

   Copies of IPR disclosures made to the IETF Secretariat and any
   assurances of licenses to be made available, or the result of an
   attempt made to obtain a general license or permission for the use of
   such proprietary rights by implementers or users of this
   specification can be obtained from the IETF on-line IPR repository at
   http://www.ietf.org/ipr.

   The IETF invites any interested party to bring to its attention any
   copyrights, patents or patent applications, or other proprietary
   rights that may cover technology that may be required to implement
   this standard.  Please address the information to the IETF at
   ietf-ipr@ietf.org.

Acknowledgement

   Funding for the RFC Editor function is provided by the IETF
   Administrative Support Activity (IASA).
------分隔线----------------------------
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
最新评论 查看所有评论
发表评论 查看所有评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 密码: 验证码:
推荐内容