~ubuntu-branches/ubuntu/natty/libgcrypt11/natty-proposed

« back to all changes in this revision

Viewing changes to cipher/md.c

  • Committer: Bazaar Package Importer
  • Author(s): Bhavani Shankar
  • Date: 2009-05-16 20:13:32 UTC
  • mfrom: (1.1.6 upstream) (2.1.3 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090516201332-czkobpu32w318i16
Tags: 1.4.4-2ubuntu1
* Merge from Debian unstable (LP: #364535), remaining changes:
  - Add libgcrypt11-udeb for use by cryptsetup-udeb.
  - Add clean-la.mk, and add a symlink for the .la
  - Install to /lib.

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, 2006 Free Software Foundation, Inc.
 
2
 * Copyright (C) 1998, 1999, 2002, 2003, 2006,
 
3
 *               2008 Free Software Foundation, Inc.
3
4
 *
4
5
 * This file is part of Libgcrypt.
5
6
 *
14
15
 * GNU Lesser General Public License for more details.
15
16
 *
16
17
 * You should have received a copy of the GNU Lesser General Public
17
 
 * License along with this program; if not, write to the Free Software
18
 
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 
18
 * License along with this program; if not, see <http://www.gnu.org/licenses/>.
19
19
 */
20
20
 
21
21
#include <config.h>
23
23
#include <stdlib.h>
24
24
#include <string.h>
25
25
#include <errno.h>
26
 
#include <assert.h>
27
26
 
28
27
#include "g10lib.h"
29
28
#include "cipher.h"
31
30
 
32
31
#include "rmd.h"
33
32
 
 
33
/* A dummy extraspec so that we do not need to tests the extraspec
 
34
   field from the module specification against NULL and instead
 
35
   directly test the respective fields of extraspecs.  */
 
36
static md_extra_spec_t dummy_extra_spec;
 
37
 
 
38
 
 
39
/* This is the list of the digest implementations included in
 
40
   libgcrypt.  */
34
41
static struct digest_table_entry
35
42
{
36
43
  gcry_md_spec_t *digest;
 
44
  md_extra_spec_t *extraspec;
37
45
  unsigned int algorithm;
 
46
  int fips_allowed; 
38
47
} digest_table[] =
39
48
  {
40
49
#if USE_CRC    
41
 
    { &_gcry_digest_spec_crc32, GCRY_MD_CRC32 },
42
 
    { &_gcry_digest_spec_crc32_rfc1510, GCRY_MD_CRC32_RFC1510 },
43
 
    { &_gcry_digest_spec_crc24_rfc2440, GCRY_MD_CRC24_RFC2440 },
 
50
    /* We allow the CRC algorithms even in FIPS mode because they are
 
51
       actually no cryptographic primitives.  */
 
52
    { &_gcry_digest_spec_crc32,   
 
53
      &dummy_extra_spec,                 GCRY_MD_CRC32, 1 },
 
54
    { &_gcry_digest_spec_crc32_rfc1510,  
 
55
      &dummy_extra_spec,                 GCRY_MD_CRC32_RFC1510, 1 },
 
56
    { &_gcry_digest_spec_crc24_rfc2440,
 
57
      &dummy_extra_spec,                 GCRY_MD_CRC24_RFC2440, 1 },
44
58
#endif
45
59
#if USE_MD4
46
 
    { &_gcry_digest_spec_md4, GCRY_MD_MD4 },
 
60
    { &_gcry_digest_spec_md4,
 
61
      &dummy_extra_spec,                 GCRY_MD_MD4 },
47
62
#endif
48
63
#if USE_MD5
49
 
    { &_gcry_digest_spec_md5, GCRY_MD_MD5 },
 
64
    { &_gcry_digest_spec_md5,
 
65
      &dummy_extra_spec,                 GCRY_MD_MD5, 1 },
50
66
#endif
51
67
#if USE_RMD160
52
 
    { &_gcry_digest_spec_rmd160, GCRY_MD_RMD160 },
 
68
    { &_gcry_digest_spec_rmd160,
 
69
      &dummy_extra_spec,                 GCRY_MD_RMD160 },
53
70
#endif
54
71
#if USE_SHA1
55
 
    { &_gcry_digest_spec_sha1, GCRY_MD_SHA1 },
 
72
    { &_gcry_digest_spec_sha1, 
 
73
      &_gcry_digest_extraspec_sha1,      GCRY_MD_SHA1, 1 },
56
74
#endif
57
75
#if USE_SHA256
58
 
    { &_gcry_digest_spec_sha256, GCRY_MD_SHA256 },
59
 
    { &_gcry_digest_spec_sha224, GCRY_MD_SHA224 },
 
76
    { &_gcry_digest_spec_sha256,
 
77
      &_gcry_digest_extraspec_sha256,    GCRY_MD_SHA256, 1 },
 
78
    { &_gcry_digest_spec_sha224,
 
79
      &_gcry_digest_extraspec_sha224,    GCRY_MD_SHA224, 1 },
60
80
#endif
61
81
#if USE_SHA512
62
 
    { &_gcry_digest_spec_sha512, GCRY_MD_SHA512 },
63
 
    { &_gcry_digest_spec_sha384, GCRY_MD_SHA384 },
 
82
    { &_gcry_digest_spec_sha512,
 
83
      &_gcry_digest_extraspec_sha512,    GCRY_MD_SHA512, 1 },
 
84
    { &_gcry_digest_spec_sha384,
 
85
      &_gcry_digest_extraspec_sha384,    GCRY_MD_SHA384, 1 },
64
86
#endif
65
87
#if USE_TIGER
66
 
    { &_gcry_digest_spec_tiger, GCRY_MD_TIGER },
 
88
    { &_gcry_digest_spec_tiger,
 
89
      &dummy_extra_spec,                 GCRY_MD_TIGER },
67
90
#endif
68
91
#if USE_WHIRLPOOL
69
 
    { &_gcry_digest_spec_whirlpool, GCRY_MD_WHIRLPOOL },
 
92
    { &_gcry_digest_spec_whirlpool,
 
93
      &dummy_extra_spec,                 GCRY_MD_WHIRLPOOL },
70
94
#endif
71
95
    { NULL },
72
96
  };
115
139
      ath_mutex_lock (&digests_registered_lock);   \
116
140
      if (! default_digests_registered)            \
117
141
        {                                          \
118
 
          gcry_md_register_default ();             \
 
142
          md_register_default ();                  \
119
143
          default_digests_registered = 1;          \
120
144
        }                                          \
121
145
      ath_mutex_unlock (&digests_registered_lock); \
145
169
/* Internal function.  Register all the ciphers included in
146
170
   CIPHER_TABLE.  Returns zero on success or an error code.  */
147
171
static void
148
 
gcry_md_register_default (void)
 
172
md_register_default (void)
149
173
{
150
174
  gcry_err_code_t err = 0;
151
175
  int i;
152
176
  
153
 
  for (i = 0; (! err) && digest_table[i].digest; i++)
154
 
    err = _gcry_module_add (&digests_registered,
155
 
                            digest_table[i].algorithm,
156
 
                            (void *) digest_table[i].digest,
157
 
                            NULL);
 
177
  for (i = 0; !err && digest_table[i].digest; i++)
 
178
    {
 
179
      if ( fips_mode ())
 
180
        {
 
181
          if (!digest_table[i].fips_allowed)
 
182
            continue;
 
183
          if (digest_table[i].algorithm == GCRY_MD_MD5
 
184
              && _gcry_enforced_fips_mode () )
 
185
            continue;  /* Do not register in enforced fips mode.  */
 
186
        }
 
187
 
 
188
      err = _gcry_module_add (&digests_registered,
 
189
                              digest_table[i].algorithm,
 
190
                              (void *) digest_table[i].digest,
 
191
                              (void *) digest_table[i].extraspec,
 
192
                              NULL);
 
193
    }
158
194
 
159
195
  if (err)
160
196
    BUG ();
217
253
   DIGEST.  On success, a new algorithm ID is stored in ALGORITHM_ID
218
254
   and a pointer representhing this module is stored in MODULE.  */
219
255
gcry_error_t
220
 
gcry_md_register (gcry_md_spec_t *digest,
221
 
                  unsigned int *algorithm_id,
222
 
                  gcry_module_t *module)
 
256
_gcry_md_register (gcry_md_spec_t *digest,
 
257
                   md_extra_spec_t *extraspec,
 
258
                   unsigned int *algorithm_id,
 
259
                   gcry_module_t *module)
223
260
{
224
261
  gcry_err_code_t err = 0;
225
262
  gcry_module_t mod;
226
263
 
 
264
  /* We do not support module loading in fips mode.  */
 
265
  if (fips_mode ())
 
266
    return gpg_error (GPG_ERR_NOT_SUPPORTED);
 
267
 
227
268
  ath_mutex_lock (&digests_registered_lock);
228
269
  err = _gcry_module_add (&digests_registered, 0,
229
 
                          (void *) digest, &mod);
 
270
                          (void *) digest, 
 
271
                          (void *)(extraspec? extraspec : &dummy_extra_spec), 
 
272
                          &mod);
230
273
  ath_mutex_unlock (&digests_registered_lock);
231
274
  
232
275
  if (! err)
431
474
 
432
475
      if (hmac)
433
476
        {
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
 
          }
441
 
          if (! ctx->macpads)
 
477
          switch (algo)
 
478
            {
 
479
              case GCRY_MD_SHA384:
 
480
              case GCRY_MD_SHA512:
 
481
                ctx->macpads_Bsize = 128;
 
482
                break;
 
483
              default:
 
484
                ctx->macpads_Bsize = 64;
 
485
                break;
 
486
            }
 
487
          ctx->macpads = gcry_malloc_secure (2*(ctx->macpads_Bsize));
 
488
          if (!ctx->macpads)
442
489
            {
443
490
              err = gpg_err_code_from_errno (errno);
444
491
              md_close (hd);
448
495
 
449
496
  if (! err)
450
497
    {
451
 
      /* FIXME: should we really do that? - yes [-wk] */
 
498
      /* Hmmm, should we really do that? - yes [-wk] */
452
499
      _gcry_fast_random_poll ();
453
500
 
454
501
      if (algo)
513
560
      log_debug ("md_enable: algorithm %d not available\n", algorithm);
514
561
      err = GPG_ERR_DIGEST_ALGO;
515
562
    }
516
 
  else
 
563
 else
517
564
    digest = (gcry_md_spec_t *) module->spec;
518
565
 
519
 
  if (! err)
 
566
  
 
567
  if (!err && algorithm == GCRY_MD_MD5 && fips_mode ())
 
568
    {
 
569
      _gcry_inactivate_fips_mode ("MD5 used");
 
570
      if (_gcry_enforced_fips_mode () )
 
571
        {
 
572
          /* We should never get to here because we do not register
 
573
             MD5 in enforced fips mode. But better throw an error.  */
 
574
          err = GPG_ERR_DIGEST_ALGO;
 
575
        }
 
576
    }
 
577
  
 
578
  if (!err)
520
579
    {
521
580
      size_t size = (sizeof (*entry)
522
581
                     + digest->contextsize
560
619
gcry_error_t
561
620
gcry_md_enable (gcry_md_hd_t hd, int algorithm)
562
621
{
563
 
  gcry_err_code_t err = md_enable (hd, algorithm);
564
 
  return gcry_error (err);
 
622
  return gcry_error (md_enable (hd, algorithm));
565
623
}
566
624
 
567
625
static gcry_err_code_t
590
648
    {
591
649
      bhd->ctx = b = (struct gcry_md_context *) ((char *) bhd + n);
592
650
      /* No need to copy the buffer due to the write above. */
593
 
      assert (ahd->bufsize == (n - sizeof (struct gcry_md_handle) + 1));
 
651
      gcry_assert (ahd->bufsize == (n - sizeof (struct gcry_md_handle) + 1));
594
652
      bhd->bufsize = ahd->bufsize;
595
653
      bhd->bufpos = 0;
596
 
      assert (! ahd->bufpos);
 
654
      gcry_assert (! ahd->bufpos);
597
655
      memcpy (b, a, sizeof *a);
598
656
      b->list = NULL;
599
657
      b->debug = NULL;
655
713
gcry_error_t
656
714
gcry_md_copy (gcry_md_hd_t *handle, gcry_md_hd_t hd)
657
715
{
658
 
  gcry_err_code_t err = md_copy (hd, handle);
 
716
  gcry_err_code_t err;
 
717
 
 
718
  err = md_copy (hd, handle);
659
719
  if (err)
660
720
    *handle = NULL;
661
721
  return gcry_error (err);
669
729
gcry_md_reset (gcry_md_hd_t a)
670
730
{
671
731
  GcryDigestEntry *r;
672
 
  
 
732
 
 
733
  /* Note: We allow this even in fips non operational mode.  */
 
734
 
673
735
  a->bufpos = a->ctx->finalized = 0;
674
736
 
675
737
  for (r = a->ctx->list; r; r = r->next)
713
775
void
714
776
gcry_md_close (gcry_md_hd_t hd)
715
777
{
 
778
  /* Note: We allow this even in fips non operational mode.  */
716
779
  md_close (hd);
717
780
}
718
781
 
771
834
 
772
835
      if (err)
773
836
        _gcry_fatal_error (err, NULL);
774
 
      md_write (om, (a->ctx->macpads)+(a->ctx->macpads_Bsize), a->ctx->macpads_Bsize);
 
837
      md_write (om, 
 
838
                (a->ctx->macpads)+(a->ctx->macpads_Bsize), 
 
839
                a->ctx->macpads_Bsize);
775
840
      md_write (om, p, dlen);
776
841
      md_final (om);
777
842
      /* Replace our digest with the mac (they have the same size). */
781
846
}
782
847
 
783
848
static gcry_err_code_t
784
 
prepare_macpads( gcry_md_hd_t hd, const byte *key, size_t keylen)
 
849
prepare_macpads (gcry_md_hd_t hd, const unsigned char *key, size_t keylen)
785
850
{
786
851
  int i;
787
 
  int algo = md_get_algo( hd );
788
 
  byte *helpkey = NULL;
789
 
  byte *ipad, *opad;
790
 
 
791
 
  if ( !algo )
792
 
    return GPG_ERR_DIGEST_ALGO; /* i.e. no algo enabled */
793
 
 
794
 
  if ( keylen > 64 ) 
 
852
  int algo = md_get_algo (hd);
 
853
  unsigned char *helpkey = NULL;
 
854
  unsigned char *ipad, *opad;
 
855
 
 
856
  if (!algo)
 
857
    return GPG_ERR_DIGEST_ALGO; /* Might happen if no algo is enabled.  */
 
858
 
 
859
  if ( keylen > hd->ctx->macpads_Bsize ) 
795
860
    {
796
 
      helpkey = gcry_malloc_secure ( md_digest_length( algo ) );
797
 
      if ( !helpkey )
 
861
      helpkey = gcry_malloc_secure (md_digest_length (algo));
 
862
      if (!helpkey)
798
863
        return gpg_err_code_from_errno (errno);
799
 
      gcry_md_hash_buffer ( algo, helpkey, key, keylen );
 
864
      gcry_md_hash_buffer (algo, helpkey, key, keylen);
800
865
      key = helpkey;
801
 
      keylen = md_digest_length( algo );
802
 
      assert ( keylen <= 64 );
 
866
      keylen = md_digest_length (algo);
 
867
      gcry_assert ( keylen <= hd->ctx->macpads_Bsize );
803
868
    }
804
869
 
805
870
  memset ( hd->ctx->macpads, 0, 2*(hd->ctx->macpads_Bsize) );
807
872
  opad = (hd->ctx->macpads)+(hd->ctx->macpads_Bsize);
808
873
  memcpy ( ipad, key, keylen );
809
874
  memcpy ( opad, key, keylen );
810
 
  for (i=0; i < (hd->ctx->macpads_Bsize); i++ ) 
 
875
  for (i=0; i < hd->ctx->macpads_Bsize; i++ ) 
811
876
    {
812
877
      ipad[i] ^= 0x36;
813
878
      opad[i] ^= 0x5c;
814
879
    }
815
 
  gcry_free( helpkey );
 
880
  gcry_free (helpkey);
816
881
 
817
882
  return GPG_ERR_NO_ERROR;
818
883
}
847
912
{
848
913
  gcry_err_code_t rc = GPG_ERR_NO_ERROR;
849
914
 
850
 
  if (! hd->ctx->macpads)
 
915
  if (!hd->ctx->macpads)
851
916
    rc = GPG_ERR_CONFLICT;
852
917
  else
853
918
    {
905
970
byte *
906
971
gcry_md_read (gcry_md_hd_t hd, int algo)
907
972
{
 
973
  /* This function is expected to always return a digest, thus we
 
974
     can't return an error which we actually should do in
 
975
     non-operational state.  */
908
976
  gcry_md_ctl (hd, GCRYCTL_FINALIZE, NULL, 0);
909
977
  return md_read (hd, algo);
910
978
}
911
979
 
912
 
/****************
913
 
 * This function combines md_final and md_read but keeps the context
914
 
 * intact.  This function can be used to calculate intermediate
915
 
 * digests.  The digest is copied into buffer and the digestlength is
916
 
 * returned.  If buffer is NULL only the needed size for buffer is returned.
917
 
 * buflen gives the max size of buffer. If the buffer is too shourt to
918
 
 * hold the complete digest, the buffer is filled with as many bytes are
919
 
 * possible and this value is returned.
920
 
 */
921
 
#if 0
922
 
static int
923
 
md_digest( gcry_md_hd_t a, int algo, byte *buffer, int buflen )
924
 
{
925
 
  struct md_digest_list_s *r = NULL;
926
 
  char *context;
927
 
  char *digest;
928
 
 
929
 
  if( a->bufpos )
930
 
    md_write( a, NULL, 0 );
931
 
 
932
 
  if( !algo ) {  /* return digest for the first algorithm */
933
 
    if( (r=a->ctx->list) && r->next )
934
 
      log_debug("more than algorithm in md_digest(0)\n");
935
 
  }
936
 
  else {
937
 
    for(r=a->ctx->list; r; r = r->next )
938
 
      if( r->algo == algo )
939
 
        break;
940
 
  }
941
 
  if( !r )
942
 
    BUG();
943
 
 
944
 
  if( !buffer )
945
 
    return r->mdlen;
946
 
 
947
 
  /* I don't want to change the interface, so I simply work on a copy
948
 
   * of the context (extra overhead - should be fixed)*/
949
 
  context = a->ctx->secure ? gcry_xmalloc_secure( r->contextsize )
950
 
    : gcry_xmalloc( r->contextsize );
951
 
  memcpy( context, r->context.c, r->contextsize );
952
 
  (*r->digest->final)( context );
953
 
  digest = (*r->digest->read)( context );
954
 
 
955
 
  if( buflen > r->mdlen )
956
 
    buflen = r->mdlen;
957
 
  memcpy( buffer, digest, buflen );
958
 
 
959
 
  gcry_free(context);
960
 
  return buflen;
961
 
}
962
 
#endif
963
980
 
964
981
/*
965
 
 * Read out an intermediate digest.  Not yet fucntional.
 
982
 * Read out an intermediate digest.  Not yet functional.
966
983
 */
967
984
gcry_err_code_t
968
985
gcry_md_get (gcry_md_hd_t hd, int algo, byte *buffer, int buflen)
973
990
  (void)buflen;
974
991
 
975
992
  /*md_digest ... */
 
993
  fips_signal_error ("unimplemented function called");
976
994
  return GPG_ERR_INTERNAL;
977
995
}
978
996
 
989
1007
{
990
1008
  if (algo == GCRY_MD_SHA1)
991
1009
    _gcry_sha1_hash_buffer (digest, buffer, length);
992
 
  else if (algo == GCRY_MD_RMD160)
 
1010
  else if (algo == GCRY_MD_RMD160 && !fips_mode () )
993
1011
    _gcry_rmd160_hash_buffer (digest, buffer, length);
994
1012
  else
995
1013
    {
996
1014
      /* For the others we do not have a fast function, so we use the
997
1015
         normal functions. */
998
1016
      gcry_md_hd_t h;
999
 
      gpg_err_code_t err = md_open (&h, algo, 0, 0);
 
1017
      gpg_err_code_t err;
 
1018
 
 
1019
      if (algo == GCRY_MD_MD5 && fips_mode ())
 
1020
        {
 
1021
          _gcry_inactivate_fips_mode ("MD5 used");
 
1022
          if (_gcry_enforced_fips_mode () )
 
1023
            {
 
1024
              /* We should never get to here because we do not register
 
1025
                 MD5 in enforced fips mode.  */
 
1026
              _gcry_fips_noreturn ();
 
1027
            }
 
1028
        }
 
1029
 
 
1030
      err = md_open (&h, algo, 0, 0);
1000
1031
      if (err)
1001
1032
        log_bug ("gcry_md_open failed for algo %d: %s",
1002
1033
                 algo, gpg_strerror (gcry_error(err)));
1013
1044
  GcryDigestEntry *r = a->ctx->list;
1014
1045
 
1015
1046
  if (r && r->next)
1016
 
    log_error("WARNING: more than algorithm in md_get_algo()\n");
 
1047
    {
 
1048
      fips_signal_error ("possible usage error");
 
1049
      log_error ("WARNING: more than one algorithm in md_get_algo()\n");
 
1050
    }
1017
1051
  return r ? r->module->mod_id : 0;
1018
1052
}
1019
1053
 
1158
1192
{
1159
1193
  static int idx=0;
1160
1194
  char buf[50];
 
1195
 
 
1196
  if (fips_mode ())
 
1197
    return;
1161
1198
  
1162
1199
  if ( md->ctx->debug )
1163
1200
    {
1244
1281
  return gcry_error (err);
1245
1282
}
1246
1283
 
 
1284
 
 
1285
/* Explicitly initialize this module.  */
1247
1286
gcry_err_code_t
1248
1287
_gcry_md_init (void)
1249
1288
{
1296
1335
 
1297
1336
  return err;
1298
1337
}
 
1338
 
 
1339
 
 
1340
/* Run the selftests for digest algorithm ALGO with optional reporting
 
1341
   function REPORT.  */
 
1342
gpg_error_t
 
1343
_gcry_md_selftest (int algo, int extended, selftest_report_func_t report)
 
1344
{
 
1345
  gcry_module_t module = NULL;
 
1346
  cipher_extra_spec_t *extraspec = NULL;
 
1347
  gcry_err_code_t ec = 0;
 
1348
 
 
1349
  REGISTER_DEFAULT_DIGESTS;
 
1350
 
 
1351
  ath_mutex_lock (&digests_registered_lock);
 
1352
  module = _gcry_module_lookup_id (digests_registered, algo);
 
1353
  if (module && !(module->flags & FLAG_MODULE_DISABLED))
 
1354
    extraspec = module->extraspec;
 
1355
  ath_mutex_unlock (&digests_registered_lock);
 
1356
  if (extraspec && extraspec->selftest)
 
1357
    ec = extraspec->selftest (algo, extended, report);
 
1358
  else
 
1359
    {
 
1360
      ec = GPG_ERR_DIGEST_ALGO;
 
1361
      if (report)
 
1362
        report ("digest", algo, "module", 
 
1363
                module && !(module->flags & FLAG_MODULE_DISABLED)?
 
1364
                "no selftest available" :
 
1365
                module? "algorithm disabled" : "algorithm not found");
 
1366
    }
 
1367
 
 
1368
  if (module)
 
1369
    {
 
1370
      ath_mutex_lock (&digests_registered_lock);
 
1371
      _gcry_module_release (module);
 
1372
      ath_mutex_unlock (&digests_registered_lock);
 
1373
    }
 
1374
  return gpg_error (ec);
 
1375
}