~ubuntu-branches/ubuntu/raring/libgcrypt11/raring

« back to all changes in this revision

Viewing changes to cipher/md.c

  • Committer: Bazaar Package Importer
  • Author(s): Steve Kowalik
  • Date: 2008-07-02 18:32:45 UTC
  • mfrom: (1.1.5 upstream) (2.1.2 lenny)
  • Revision ID: james.westby@ubuntu.com-20080702183245-b1p9zumbhmq9wk4g
Tags: 1.4.1-1ubuntu1
* Merge from Debian unstable.
* Remaining Ubuntu changes:
  - Add libgcrypt11-udeb package.
  - Add clean-la.mk, and add a symlink for the .la
* Ubuntu changes dropped:
  - Build-Depends changes.
  - Drop patch 20_socket_nsl_linkage.diff, basically applied upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* md.c  -  message digest dispatcher
2
 
 * Copyright (C) 1998, 1999, 2002, 2003 Free Software Foundation, Inc.
 
2
 * Copyright (C) 1998, 1999, 2002, 2003, 2006 Free Software Foundation, Inc.
3
3
 *
4
4
 * This file is part of Libgcrypt.
5
5
 *
56
56
#endif
57
57
#if USE_SHA256
58
58
    { &_gcry_digest_spec_sha256, GCRY_MD_SHA256 },
 
59
    { &_gcry_digest_spec_sha224, GCRY_MD_SHA224 },
59
60
#endif
60
61
#if USE_SHA512
61
62
    { &_gcry_digest_spec_sha512, GCRY_MD_SHA512 },
64
65
#if USE_TIGER
65
66
    { &_gcry_digest_spec_tiger, GCRY_MD_TIGER },
66
67
#endif
 
68
#if USE_WHIRLPOOL
 
69
    { &_gcry_digest_spec_whirlpool, GCRY_MD_WHIRLPOOL },
 
70
#endif
67
71
    { NULL },
68
72
  };
69
73
 
97
101
  int finalized;
98
102
  GcryDigestEntry *list;
99
103
  byte *macpads;
 
104
  int macpads_Bsize;             /* Blocksize as used for the HMAC pads. */
100
105
};
101
106
 
102
107
 
125
130
static gcry_err_code_t md_enable (gcry_md_hd_t hd, int algo);
126
131
static gcry_err_code_t md_copy (gcry_md_hd_t a, gcry_md_hd_t *b);
127
132
static void md_close (gcry_md_hd_t a);
128
 
static void md_write (gcry_md_hd_t a, byte *inbuf, size_t inlen);
 
133
static void md_write (gcry_md_hd_t a, const void *inbuf, size_t inlen);
129
134
static void md_final(gcry_md_hd_t a);
130
135
static byte *md_read( gcry_md_hd_t a, int algo );
131
136
static int md_get_algo( gcry_md_hd_t a );
132
137
static int md_digest_length( int algo );
133
138
static const byte *md_asn_oid( int algo, size_t *asnlen, size_t *mdlen );
134
 
static void md_start_debug( gcry_md_hd_t a, char *suffix );
135
 
static void md_stop_debug( gcry_md_hd_t a );
 
139
static void md_start_debug ( gcry_md_hd_t a, const char *suffix );
 
140
static void md_stop_debug ( gcry_md_hd_t a );
136
141
 
137
142
 
138
143
 
298
303
  ret = search_oid (string, &algorithm, NULL);
299
304
  if (! ret)
300
305
    {
301
 
      /* Not found, search for an acording diget name.  */
 
306
      /* Not found, search a matching digest name.  */
302
307
      digest = gcry_md_lookup_name (string);
303
308
      if (digest)
304
309
        {
426
431
 
427
432
      if (hmac)
428
433
        {
429
 
          ctx->macpads = gcry_malloc_secure (128);
 
434
          if ( (GCRY_MD_SHA384 == algo) || (GCRY_MD_SHA512 == algo) ) {
 
435
            ctx->macpads_Bsize = 128;
 
436
            ctx->macpads = gcry_malloc_secure (2*(ctx->macpads_Bsize));
 
437
          } else {
 
438
            ctx->macpads_Bsize = 64;
 
439
            ctx->macpads = gcry_malloc_secure (2*(ctx->macpads_Bsize));
 
440
          }
430
441
          if (! ctx->macpads)
431
442
            {
 
443
              err = gpg_err_code_from_errno (errno);
432
444
              md_close (hd);
433
 
              err = gpg_err_code_from_errno (errno);
434
445
            }
435
446
        }
436
447
    }
588
599
      b->debug = NULL;
589
600
      if (a->macpads)
590
601
        {
591
 
          b->macpads = gcry_malloc_secure (128);
 
602
          b->macpads = gcry_malloc_secure (2*(a->macpads_Bsize));
592
603
          if (! b->macpads)
593
604
            {
 
605
              err = gpg_err_code_from_errno (errno);
594
606
              md_close (bhd);
595
 
              err = gpg_err_code_from_errno (errno);
596
607
            }
597
608
          else
598
 
            memcpy (b->macpads, a->macpads, 128);
 
609
            memcpy (b->macpads, a->macpads, (2*(a->macpads_Bsize)));
599
610
        }
600
611
    }
601
612
 
602
613
  /* Copy the complete list of algorithms.  The copied list is
603
614
     reversed, but that doesn't matter. */
604
 
  if (! err)
605
 
    for (ar = a->list; ar; ar = ar->next)
606
 
      {
607
 
        if (a->secure)
608
 
          br = gcry_xmalloc_secure (sizeof *br
609
 
                                    + ar->digest->contextsize
610
 
                                    - sizeof(ar->context));
611
 
        else
612
 
          br = gcry_xmalloc (sizeof *br
613
 
                             + ar->digest->contextsize
614
 
                             - sizeof (ar->context));
615
 
        memcpy (br, ar,
616
 
                sizeof (*br) + ar->digest->contextsize - sizeof (ar->context));
617
 
        br->next = b->list;
618
 
        b->list = br;
619
 
 
620
 
        /* Add a reference to the module.  */
621
 
        ath_mutex_lock (&digests_registered_lock);
622
 
        _gcry_module_use (br->module);
623
 
        ath_mutex_unlock (&digests_registered_lock);
624
 
       }
625
 
 
626
 
  if (a->debug)
 
615
  if (!err)
 
616
    {
 
617
      for (ar = a->list; ar; ar = ar->next)
 
618
        {
 
619
          if (a->secure)
 
620
            br = gcry_malloc_secure (sizeof *br
 
621
                                     + ar->digest->contextsize
 
622
                                     - sizeof(ar->context));
 
623
          else
 
624
            br = gcry_malloc (sizeof *br
 
625
                              + ar->digest->contextsize
 
626
                              - sizeof (ar->context));
 
627
          if (!br)
 
628
            {
 
629
              err = gpg_err_code_from_errno (errno);
 
630
              md_close (bhd);
 
631
              break;
 
632
            }
 
633
 
 
634
          memcpy (br, ar, (sizeof (*br) + ar->digest->contextsize
 
635
                           - sizeof (ar->context)));
 
636
          br->next = b->list;
 
637
          b->list = br;
 
638
          
 
639
          /* Add a reference to the module.  */
 
640
          ath_mutex_lock (&digests_registered_lock);
 
641
          _gcry_module_use (br->module);
 
642
          ath_mutex_unlock (&digests_registered_lock);
 
643
        }
 
644
    }
 
645
 
 
646
  if (a->debug && !err)
627
647
    md_start_debug (bhd, "unknown");
628
648
 
629
 
  if (! err)
 
649
  if (!err)
630
650
    *b_hd = bhd;
631
651
 
632
652
  return err;
658
678
      (*r->digest->init) (&r->context.c);
659
679
    }
660
680
  if (a->ctx->macpads)
661
 
    md_write (a, a->ctx->macpads, 64); /* inner pad */
 
681
    md_write (a, a->ctx->macpads, a->ctx->macpads_Bsize); /* inner pad */
662
682
}
663
683
 
664
684
static void
682
702
 
683
703
  if (a->ctx->macpads)
684
704
    {
685
 
      wipememory (a->ctx->macpads, 128);
 
705
      wipememory (a->ctx->macpads, 2*(a->ctx->macpads_Bsize));
686
706
      gcry_free(a->ctx->macpads);
687
707
    }
688
708
 
697
717
}
698
718
 
699
719
static void
700
 
md_write (gcry_md_hd_t a, byte *inbuf, size_t inlen)
 
720
md_write (gcry_md_hd_t a, const void *inbuf, size_t inlen)
701
721
{
702
722
  GcryDigestEntry *r;
703
723
  
721
741
void
722
742
gcry_md_write (gcry_md_hd_t hd, const void *inbuf, size_t inlen)
723
743
{
724
 
  md_write (hd, (unsigned char *) inbuf, inlen);
 
744
  md_write (hd, inbuf, inlen);
725
745
}
726
746
 
727
747
static void
751
771
 
752
772
      if (err)
753
773
        _gcry_fatal_error (err, NULL);
754
 
      md_write (om, a->ctx->macpads+64, 64);
 
774
      md_write (om, (a->ctx->macpads)+(a->ctx->macpads_Bsize), a->ctx->macpads_Bsize);
755
775
      md_write (om, p, dlen);
756
776
      md_final (om);
757
777
      /* Replace our digest with the mac (they have the same size). */
782
802
      assert ( keylen <= 64 );
783
803
    }
784
804
 
785
 
  memset ( hd->ctx->macpads, 0, 128 );
 
805
  memset ( hd->ctx->macpads, 0, 2*(hd->ctx->macpads_Bsize) );
786
806
  ipad = hd->ctx->macpads;
787
 
  opad = hd->ctx->macpads+64;
 
807
  opad = (hd->ctx->macpads)+(hd->ctx->macpads_Bsize);
788
808
  memcpy ( ipad, key, keylen );
789
809
  memcpy ( opad, key, keylen );
790
 
  for (i=0; i < 64; i++ ) 
 
810
  for (i=0; i < (hd->ctx->macpads_Bsize); i++ ) 
791
811
    {
792
812
      ipad[i] ^= 0x36;
793
813
      opad[i] ^= 0x5c;
800
820
gcry_error_t
801
821
gcry_md_ctl (gcry_md_hd_t hd, int cmd, void *buffer, size_t buflen)
802
822
{
803
 
  unsigned char *buf = (unsigned char *)buffer;
804
823
  gcry_err_code_t rc = 0;
805
824
  
806
825
  switch (cmd)
809
828
      md_final (hd);
810
829
      break;
811
830
    case GCRYCTL_SET_KEY:
812
 
      rc = gcry_err_code (gcry_md_setkey (hd, buf, buflen));
 
831
      rc = gcry_err_code (gcry_md_setkey (hd, buffer, buflen));
813
832
      break;
814
833
    case GCRYCTL_START_DUMP:
815
 
      md_start_debug (hd, (char*)buf);
 
834
      md_start_debug (hd, buffer);
816
835
      break;
817
836
    case GCRYCTL_STOP_DUMP:
818
 
      md_stop_debug( hd );
 
837
      md_stop_debug ( hd );
819
838
      break;
820
839
    default:
821
840
      rc = GPG_ERR_INV_OP;
840
859
  return gcry_error (rc);
841
860
}
842
861
 
 
862
/* The new debug interface.  If SUFFIX is a string it creates an debug
 
863
   file for the context HD.  IF suffix is NULL, the file is closed and
 
864
   debugging is stopped.  */
 
865
void
 
866
gcry_md_debug (gcry_md_hd_t hd, const char *suffix)
 
867
{
 
868
  if (suffix)
 
869
    md_start_debug (hd, suffix);
 
870
  else
 
871
    md_stop_debug (hd);
 
872
}
 
873
 
 
874
 
843
875
 
844
876
/****************
845
877
 * if ALGO is null get the digest for the used algo (which should be only one)
853
885
    {
854
886
      /* return the first algorithm */
855
887
      if (r && r->next)
856
 
        log_debug("more than algorithm in md_read(0)\n");
 
888
        log_debug ("more than one algorithm in md_read(0)\n");
857
889
      return r->digest->read( &r->context.c );
858
890
    }
859
891
  else
935
967
gcry_err_code_t
936
968
gcry_md_get (gcry_md_hd_t hd, int algo, byte *buffer, int buflen)
937
969
{
 
970
  (void)hd;
 
971
  (void)algo;
 
972
  (void)buffer;
 
973
  (void)buflen;
 
974
 
938
975
  /*md_digest ... */
939
976
  return GPG_ERR_INTERNAL;
940
977
}
1082
1119
      break;
1083
1120
 
1084
1121
    case GCRYCTL_GET_ASNOID:
1085
 
      {
1086
 
        const char unsigned *asn;
1087
 
        size_t asnlen;
1088
 
 
1089
 
        asn = md_asn_oid (algo, &asnlen, NULL);
1090
 
        if (buffer && (*nbytes >= asnlen))
 
1122
      /* We need to check that the algo is available because
 
1123
         md_asn_oid would otherwise raise an assertion. */
 
1124
      err = check_digest_algo (algo);
 
1125
      if (!err)
 
1126
        {
 
1127
          const char unsigned *asn;
 
1128
          size_t asnlen;
 
1129
          
 
1130
          asn = md_asn_oid (algo, &asnlen, NULL);
 
1131
          if (buffer && (*nbytes >= asnlen))
1091
1132
          {
1092
1133
            memcpy (buffer, asn, asnlen);
1093
1134
            *nbytes = asnlen;
1094
1135
          }
1095
 
        else if ((! buffer) && nbytes)
1096
 
          *nbytes = asnlen;
1097
 
        else
1098
 
          {
1099
 
            if (buffer)
1100
 
              err = GPG_ERR_TOO_SHORT;
1101
 
            else
1102
 
              err = GPG_ERR_INV_ARG;
1103
 
          }
1104
 
        break;
1105
 
      }
 
1136
          else if (!buffer && nbytes)
 
1137
            *nbytes = asnlen;
 
1138
          else
 
1139
            {
 
1140
              if (buffer)
 
1141
                err = GPG_ERR_TOO_SHORT;
 
1142
              else
 
1143
                err = GPG_ERR_INV_ARG;
 
1144
            }
 
1145
        }
 
1146
      break;
1106
1147
 
1107
1148
  default:
1108
1149
    err = GPG_ERR_INV_OP;
1113
1154
 
1114
1155
 
1115
1156
static void
1116
 
md_start_debug( gcry_md_hd_t md, char *suffix )
 
1157
md_start_debug ( gcry_md_hd_t md, const char *suffix )
1117
1158
{
1118
1159
  static int idx=0;
1119
1160
  char buf[50];
1120
 
 
1121
 
  if( md->ctx->debug ) {
1122
 
    log_debug("Oops: md debug already started\n");
1123
 
    return;
1124
 
  }
 
1161
  
 
1162
  if ( md->ctx->debug )
 
1163
    {
 
1164
      log_debug("Oops: md debug already started\n");
 
1165
      return;
 
1166
    }
1125
1167
  idx++;
1126
 
  sprintf(buf, "dbgmd-%05d.%.10s", idx, suffix );
 
1168
  snprintf (buf, DIM(buf)-1, "dbgmd-%05d.%.10s", idx, suffix );
1127
1169
  md->ctx->debug = fopen(buf, "w");
1128
 
  if( !md->ctx->debug )
 
1170
  if ( !md->ctx->debug )
1129
1171
    log_debug("md debug: can't open %s\n", buf );
1130
1172
}
1131
1173
 
1132
1174
static void
1133
1175
md_stop_debug( gcry_md_hd_t md )
1134
1176
{
1135
 
  if( md->ctx->debug ) {
1136
 
    if( md->bufpos )
1137
 
      md_write( md, NULL, 0 );
1138
 
    fclose(md->ctx->debug);
1139
 
    md->ctx->debug = NULL;
1140
 
  }
 
1177
  if ( md->ctx->debug )
 
1178
    {
 
1179
      if ( md->bufpos )
 
1180
        md_write ( md, NULL, 0 );
 
1181
      fclose (md->ctx->debug);
 
1182
      md->ctx->debug = NULL;
 
1183
    }
 
1184
 
1141
1185
#ifdef HAVE_U64_TYPEDEF
1142
1186
  {  /* a kludge to pull in the __muldi3 for Solaris */
1143
1187
    volatile u32 a = (u32)(ulong)md;
1156
1200
 *      Returns 1 when the handle works on secured memory
1157
1201
 *      otherwise 0 is returned.  There is no error return.
1158
1202
 *  GCRYCTL_IS_ALGO_ENABLED:
1159
 
 *     Returns 1 if the algo is enanled for that handle.
 
1203
 *     Returns 1 if the algo is enabled for that handle.
1160
1204
 *     The algo must be passed as the address of an int.
1161
1205
 */
1162
1206
gcry_error_t