Annotation of embedaddon/dnsmasq/src/crypto.c, revision 1.1.1.1

1.1       misho       1: /* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
                      2: 
                      3:    This program is free software; you can redistribute it and/or modify
                      4:    it under the terms of the GNU General Public License as published by
                      5:    the Free Software Foundation; version 2 dated June, 1991, or
                      6:    (at your option) version 3 dated 29 June, 2007.
                      7:  
                      8:    This program is distributed in the hope that it will be useful,
                      9:    but WITHOUT ANY WARRANTY; without even the implied warranty of
                     10:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     11:    GNU General Public License for more details.
                     12:      
                     13:    You should have received a copy of the GNU General Public License
                     14:    along with this program.  If not, see <http://www.gnu.org/licenses/>.
                     15: */
                     16: 
                     17: #include "dnsmasq.h"
                     18: 
                     19: #ifdef HAVE_DNSSEC
                     20: 
                     21: #include <nettle/rsa.h>
                     22: #include <nettle/ecdsa.h>
                     23: #include <nettle/ecc-curve.h>
                     24: #include <nettle/eddsa.h>
                     25: #if NETTLE_VERSION_MAJOR == 3 && NETTLE_VERSION_MINOR >= 6
                     26: #  include <nettle/gostdsa.h>
                     27: #endif
                     28: #endif
                     29: 
                     30: #if defined(HAVE_DNSSEC) || defined(HAVE_CRYPTOHASH)
                     31: #include <nettle/nettle-meta.h>
                     32: #include <nettle/bignum.h>
                     33: 
                     34: /* Implement a "hash-function" to the nettle API, which simply returns
                     35:    the input data, concatenated into a single, statically maintained, buffer.
                     36: 
                     37:    Used for the EdDSA sigs, which operate on the whole message, rather 
                     38:    than a digest. */
                     39: 
                     40: struct null_hash_digest
                     41: {
                     42:   uint8_t *buff;
                     43:   size_t len;
                     44: };
                     45: 
                     46: struct null_hash_ctx
                     47: {
                     48:   size_t len;
                     49: };
                     50: 
                     51: static size_t null_hash_buff_sz = 0;
                     52: static uint8_t *null_hash_buff = NULL;
                     53: #define BUFF_INCR 128
                     54: 
                     55: static void null_hash_init(void *ctx)
                     56: {
                     57:   ((struct null_hash_ctx *)ctx)->len = 0;
                     58: }
                     59: 
                     60: static void null_hash_update(void *ctxv, size_t length, const uint8_t *src)
                     61: {
                     62:   struct null_hash_ctx *ctx = ctxv;
                     63:   size_t new_len = ctx->len + length;
                     64:   
                     65:   if (new_len > null_hash_buff_sz)
                     66:     {
                     67:       uint8_t *new;
                     68:       
                     69:       if (!(new = whine_malloc(new_len + BUFF_INCR)))
                     70:        return;
                     71: 
                     72:       if (null_hash_buff)
                     73:        {
                     74:          if (ctx->len != 0)
                     75:            memcpy(new, null_hash_buff, ctx->len);
                     76:          free(null_hash_buff);
                     77:        }
                     78:       
                     79:       null_hash_buff_sz = new_len + BUFF_INCR;
                     80:       null_hash_buff = new;
                     81:     }
                     82: 
                     83:   memcpy(null_hash_buff + ctx->len, src, length);
                     84:   ctx->len += length;
                     85: }
                     86:  
                     87: 
                     88: static void null_hash_digest(void *ctx, size_t length, uint8_t *dst)
                     89: {
                     90:   (void)length;
                     91:   
                     92:   ((struct null_hash_digest *)dst)->buff = null_hash_buff;
                     93:   ((struct null_hash_digest *)dst)->len = ((struct null_hash_ctx *)ctx)->len;
                     94: }
                     95: 
                     96: static struct nettle_hash null_hash = {
                     97:   "null_hash",
                     98:   sizeof(struct null_hash_ctx),
                     99:   sizeof(struct null_hash_digest),
                    100:   0,
                    101:   (nettle_hash_init_func *) null_hash_init,
                    102:   (nettle_hash_update_func *) null_hash_update,
                    103:   (nettle_hash_digest_func *) null_hash_digest
                    104: };
                    105: 
                    106: /* Find pointer to correct hash function in nettle library */
                    107: const struct nettle_hash *hash_find(char *name)
                    108: {
                    109:   if (!name)
                    110:     return NULL;
                    111:   
                    112:   /* We provide a "null" hash which returns the input data as digest. */
                    113:   if (strcmp(null_hash.name, name) == 0)
                    114:     return &null_hash;
                    115: 
                    116:   /* libnettle >= 3.4 provides nettle_lookup_hash() which avoids nasty ABI
                    117:      incompatibilities if sizeof(nettle_hashes) changes between library
                    118:      versions. It also #defines nettle_hashes, so use that to tell
                    119:      if we have the new facilities. */
                    120:   
                    121: #ifdef nettle_hashes
                    122:   return nettle_lookup_hash(name);
                    123: #else
                    124:   {
                    125:     int i;
                    126: 
                    127:     for (i = 0; nettle_hashes[i]; i++)
                    128:       if (strcmp(nettle_hashes[i]->name, name) == 0)
                    129:        return nettle_hashes[i];
                    130:   }
                    131:   
                    132:   return NULL;
                    133: #endif
                    134: }
                    135: 
                    136: /* expand ctx and digest memory allocations if necessary and init hash function */
                    137: int hash_init(const struct nettle_hash *hash, void **ctxp, unsigned char **digestp)
                    138: {
                    139:   static void *ctx = NULL;
                    140:   static unsigned char *digest = NULL;
                    141:   static unsigned int ctx_sz = 0;
                    142:   static unsigned int digest_sz = 0;
                    143: 
                    144:   void *new;
                    145: 
                    146:   if (ctx_sz < hash->context_size)
                    147:     {
                    148:       if (!(new = whine_malloc(hash->context_size)))
                    149:        return 0;
                    150:       if (ctx)
                    151:        free(ctx);
                    152:       ctx = new;
                    153:       ctx_sz = hash->context_size;
                    154:     }
                    155:   
                    156:   if (digest_sz < hash->digest_size)
                    157:     {
                    158:       if (!(new = whine_malloc(hash->digest_size)))
                    159:        return 0;
                    160:       if (digest)
                    161:        free(digest);
                    162:       digest = new;
                    163:       digest_sz = hash->digest_size;
                    164:     }
                    165: 
                    166:   *ctxp = ctx;
                    167:   *digestp = digest;
                    168: 
                    169:   hash->init(ctx);
                    170: 
                    171:   return 1;
                    172: }
                    173: 
                    174: #endif
                    175: 
                    176: #ifdef HAVE_DNSSEC
                    177:   
                    178: static int dnsmasq_rsa_verify(struct blockdata *key_data, unsigned int key_len, unsigned char *sig, size_t sig_len,
                    179:                              unsigned char *digest, size_t digest_len, int algo)
                    180: {
                    181:   unsigned char *p;
                    182:   size_t exp_len;
                    183:   
                    184:   static struct rsa_public_key *key = NULL;
                    185:   static mpz_t sig_mpz;
                    186: 
                    187:   (void)digest_len;
                    188:   
                    189:   if (key == NULL)
                    190:     {
                    191:       if (!(key = whine_malloc(sizeof(struct rsa_public_key))))
                    192:        return 0;
                    193:       
                    194:       nettle_rsa_public_key_init(key);
                    195:       mpz_init(sig_mpz);
                    196:     }
                    197:   
                    198:   if ((key_len < 3) || !(p = blockdata_retrieve(key_data, key_len, NULL)))
                    199:     return 0;
                    200:   
                    201:   key_len--;
                    202:   if ((exp_len = *p++) == 0)
                    203:     {
                    204:       GETSHORT(exp_len, p);
                    205:       key_len -= 2;
                    206:     }
                    207:   
                    208:   if (exp_len >= key_len)
                    209:     return 0;
                    210:   
                    211:   key->size =  key_len - exp_len;
                    212:   mpz_import(key->e, exp_len, 1, 1, 0, 0, p);
                    213:   mpz_import(key->n, key->size, 1, 1, 0, 0, p + exp_len);
                    214: 
                    215:   mpz_import(sig_mpz, sig_len, 1, 1, 0, 0, sig);
                    216:   
                    217:   switch (algo)
                    218:     {
                    219:     case 5: case 7:
                    220:       return nettle_rsa_sha1_verify_digest(key, digest, sig_mpz);
                    221:     case 8:
                    222:       return nettle_rsa_sha256_verify_digest(key, digest, sig_mpz);
                    223:     case 10:
                    224:       return nettle_rsa_sha512_verify_digest(key, digest, sig_mpz);
                    225:     }
                    226: 
                    227:   return 0;
                    228: }  
                    229: 
                    230: static int dnsmasq_ecdsa_verify(struct blockdata *key_data, unsigned int key_len, 
                    231:                                unsigned char *sig, size_t sig_len,
                    232:                                unsigned char *digest, size_t digest_len, int algo)
                    233: {
                    234:   unsigned char *p;
                    235:   unsigned int t;
                    236:   struct ecc_point *key;
                    237: 
                    238:   static struct ecc_point *key_256 = NULL, *key_384 = NULL;
                    239:   static mpz_t x, y;
                    240:   static struct dsa_signature *sig_struct;
                    241: #if NETTLE_VERSION_MAJOR == 3 && NETTLE_VERSION_MINOR < 4
                    242: #define nettle_get_secp_256r1() (&nettle_secp_256r1)
                    243: #define nettle_get_secp_384r1() (&nettle_secp_384r1)
                    244: #endif
                    245:   
                    246:   if (!sig_struct)
                    247:     {
                    248:       if (!(sig_struct = whine_malloc(sizeof(struct dsa_signature))))
                    249:        return 0;
                    250:       
                    251:       nettle_dsa_signature_init(sig_struct);
                    252:       mpz_init(x);
                    253:       mpz_init(y);
                    254:     }
                    255:   
                    256:   switch (algo)
                    257:     {
                    258:     case 13:
                    259:       if (!key_256)
                    260:        {
                    261:          if (!(key_256 = whine_malloc(sizeof(struct ecc_point))))
                    262:            return 0;
                    263:          
                    264:          nettle_ecc_point_init(key_256, nettle_get_secp_256r1());
                    265:        }
                    266:       
                    267:       key = key_256;
                    268:       t = 32;
                    269:       break;
                    270:       
                    271:     case 14:
                    272:       if (!key_384)
                    273:        {
                    274:          if (!(key_384 = whine_malloc(sizeof(struct ecc_point))))
                    275:            return 0;
                    276:          
                    277:          nettle_ecc_point_init(key_384, nettle_get_secp_384r1());
                    278:        }
                    279:       
                    280:       key = key_384;
                    281:       t = 48;
                    282:       break;
                    283:         
                    284:     default:
                    285:       return 0;
                    286:     }
                    287:   
                    288:   if (sig_len != 2*t || key_len != 2*t ||
                    289:       !(p = blockdata_retrieve(key_data, key_len, NULL)))
                    290:     return 0;
                    291:   
                    292:   mpz_import(x, t , 1, 1, 0, 0, p);
                    293:   mpz_import(y, t , 1, 1, 0, 0, p + t);
                    294: 
                    295:   if (!ecc_point_set(key, x, y))
                    296:     return 0;
                    297:   
                    298:   mpz_import(sig_struct->r, t, 1, 1, 0, 0, sig);
                    299:   mpz_import(sig_struct->s, t, 1, 1, 0, 0, sig + t);
                    300:   
                    301:   return nettle_ecdsa_verify(key, digest_len, digest, sig_struct);
                    302: }
                    303: 
                    304: #if NETTLE_VERSION_MAJOR == 3 && NETTLE_VERSION_MINOR >= 6
                    305: static int dnsmasq_gostdsa_verify(struct blockdata *key_data, unsigned int key_len, 
                    306:                                  unsigned char *sig, size_t sig_len,
                    307:                                  unsigned char *digest, size_t digest_len, int algo)
                    308: {
                    309:   unsigned char *p;
                    310:   
                    311:   static struct ecc_point *gost_key = NULL;
                    312:   static mpz_t x, y;
                    313:   static struct dsa_signature *sig_struct;
                    314: 
                    315:   if (algo != 12 ||
                    316:       sig_len != 64 || key_len != 64 ||
                    317:       !(p = blockdata_retrieve(key_data, key_len, NULL)))
                    318:     return 0;
                    319:   
                    320:   if (!sig_struct)
                    321:     {
                    322:       if (!(sig_struct = whine_malloc(sizeof(struct dsa_signature))) ||
                    323:          !(gost_key = whine_malloc(sizeof(struct ecc_point))))
                    324:        return 0;
                    325:       
                    326:       nettle_dsa_signature_init(sig_struct);
                    327:       nettle_ecc_point_init(gost_key, nettle_get_gost_gc256b());
                    328:       mpz_init(x);
                    329:       mpz_init(y);
                    330:     }
                    331:     
                    332:   mpz_import(x, 32 , 1, 1, 0, 0, p);
                    333:   mpz_import(y, 32 , 1, 1, 0, 0, p + 32);
                    334: 
                    335:   if (!ecc_point_set(gost_key, x, y))
                    336:     return 0;
                    337:   
                    338:   mpz_import(sig_struct->r, 32, 1, 1, 0, 0, sig);
                    339:   mpz_import(sig_struct->s, 32, 1, 1, 0, 0, sig + 32);
                    340:   
                    341:   return nettle_gostdsa_verify(gost_key, digest_len, digest, sig_struct);
                    342: }
                    343: #endif
                    344: 
                    345: static int dnsmasq_eddsa_verify(struct blockdata *key_data, unsigned int key_len, 
                    346:                                unsigned char *sig, size_t sig_len,
                    347:                                unsigned char *digest, size_t digest_len, int algo)
                    348: {
                    349:   unsigned char *p;
                    350:    
                    351:   if (digest_len != sizeof(struct null_hash_digest) ||
                    352:       !(p = blockdata_retrieve(key_data, key_len, NULL)))
                    353:     return 0;
                    354:   
                    355:   /* The "digest" returned by the null_hash function is simply a struct null_hash_digest
                    356:      which has a pointer to the actual data and a length, because the buffer
                    357:      may need to be extended during "hashing". */
                    358:   
                    359:   switch (algo)
                    360:     {
                    361:     case 15:
                    362:       if (key_len != ED25519_KEY_SIZE ||
                    363:          sig_len != ED25519_SIGNATURE_SIZE)
                    364:        return 0;
                    365: 
                    366:       return ed25519_sha512_verify(p,
                    367:                                   ((struct null_hash_digest *)digest)->len,
                    368:                                   ((struct null_hash_digest *)digest)->buff,
                    369:                                   sig);
                    370:       
                    371: #if NETTLE_VERSION_MAJOR == 3 && NETTLE_VERSION_MINOR >= 6
                    372:     case 16:
                    373:       if (key_len != ED448_KEY_SIZE ||
                    374:          sig_len != ED448_SIGNATURE_SIZE)
                    375:        return 0;
                    376: 
                    377:       return ed448_shake256_verify(p,
                    378:                                   ((struct null_hash_digest *)digest)->len,
                    379:                                   ((struct null_hash_digest *)digest)->buff,
                    380:                                   sig);
                    381: #endif
                    382: 
                    383:     }
                    384: 
                    385:   return 0;
                    386: }
                    387: 
                    388: static int (*verify_func(int algo))(struct blockdata *key_data, unsigned int key_len, unsigned char *sig, size_t sig_len,
                    389:                             unsigned char *digest, size_t digest_len, int algo)
                    390: {
                    391:     
                    392:   /* Ensure at runtime that we have support for this digest */
                    393:   if (!hash_find(algo_digest_name(algo)))
                    394:     return NULL;
                    395:   
                    396:   /* This switch defines which sig algorithms we support, can't introspect Nettle for that. */
                    397:   switch (algo)
                    398:     {
                    399:     case 5: case 7: case 8: case 10:
                    400:       return dnsmasq_rsa_verify;
                    401: 
                    402: #if NETTLE_VERSION_MAJOR == 3 && NETTLE_VERSION_MINOR >= 6
                    403:     case 12:
                    404:       return dnsmasq_gostdsa_verify;
                    405: #endif
                    406:       
                    407:     case 13: case 14:
                    408:       return dnsmasq_ecdsa_verify;
                    409: 
                    410:     case 15: case 16:
                    411:       return dnsmasq_eddsa_verify;
                    412:     }
                    413:   
                    414:   return NULL;
                    415: }
                    416: 
                    417: int verify(struct blockdata *key_data, unsigned int key_len, unsigned char *sig, size_t sig_len,
                    418:           unsigned char *digest, size_t digest_len, int algo)
                    419: {
                    420: 
                    421:   int (*func)(struct blockdata *key_data, unsigned int key_len, unsigned char *sig, size_t sig_len,
                    422:              unsigned char *digest, size_t digest_len, int algo);
                    423:   
                    424:   func = verify_func(algo);
                    425:   
                    426:   if (!func)
                    427:     return 0;
                    428: 
                    429:   return (*func)(key_data, key_len, sig, sig_len, digest, digest_len, algo);
                    430: }
                    431: 
                    432: /* Note the ds_digest_name(), algo_digest_name() and nsec3_digest_name()
                    433:    define which algo numbers we support. If algo_digest_name() returns
                    434:    non-NULL for an algorithm number, we assume that algorithm is 
                    435:    supported by verify(). */
                    436: 
                    437: /* http://www.iana.org/assignments/ds-rr-types/ds-rr-types.xhtml */
                    438: char *ds_digest_name(int digest)
                    439: {
                    440:   switch (digest)
                    441:     {
                    442:     case 1: return "sha1";
                    443:     case 2: return "sha256";
                    444:     case 3: return "gosthash94";
                    445:     case 4: return "sha384";
                    446:     default: return NULL;
                    447:     }
                    448: }
                    449:  
                    450: /* http://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xhtml */
                    451: char *algo_digest_name(int algo)
                    452: {
                    453:   switch (algo)
                    454:     {
                    455:     case 1: return NULL;          /* RSA/MD5 - Must Not Implement.  RFC 6944 para 2.3. */
                    456:     case 2: return NULL;          /* Diffie-Hellman */
                    457:     case 3: return NULL; ;        /* DSA/SHA1 - Must Not Implement. RFC 8624 section 3.1 */ 
                    458:     case 5: return "sha1";        /* RSA/SHA1 */
                    459:     case 6: return NULL;          /* DSA-NSEC3-SHA1 - Must Not Implement. RFC 8624 section 3.1 */
                    460:     case 7: return "sha1";        /* RSASHA1-NSEC3-SHA1 */
                    461:     case 8: return "sha256";      /* RSA/SHA-256 */
                    462:     case 10: return "sha512";     /* RSA/SHA-512 */
                    463:     case 12: return "gosthash94"; /* ECC-GOST */
                    464:     case 13: return "sha256";     /* ECDSAP256SHA256 */
                    465:     case 14: return "sha384";     /* ECDSAP384SHA384 */        
                    466:     case 15: return "null_hash";  /* ED25519 */
                    467:     case 16: return "null_hash";  /* ED448 */
                    468:     default: return NULL;
                    469:     }
                    470: }
                    471:   
                    472: /* http://www.iana.org/assignments/dnssec-nsec3-parameters/dnssec-nsec3-parameters.xhtml */
                    473: char *nsec3_digest_name(int digest)
                    474: {
                    475:   switch (digest)
                    476:     {
                    477:     case 1: return "sha1";
                    478:     default: return NULL;
                    479:     }
                    480: }
                    481: 
                    482: #endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>