Annotation of embedaddon/dnsmasq/src/hash-questions.c, revision 1.1.1.1

1.1       misho       1: /* Copyright (c) 2012-2020 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: 
                     18: /* Hash the question section. This is used to safely detect query 
                     19:    retransmission and to detect answers to questions we didn't ask, which 
                     20:    might be poisoning attacks. Note that we decode the name rather 
                     21:    than CRC the raw bytes, since replies might be compressed differently. 
                     22:    We ignore case in the names for the same reason. 
                     23: 
                     24:    The hash used is SHA-256. If we're building with DNSSEC support,
                     25:    we use the Nettle cypto library. If not, we prefer not to
                     26:    add a dependency on Nettle, and use a stand-alone implementation. 
                     27: */
                     28: 
                     29: #include "dnsmasq.h"
                     30: 
                     31: #if defined(HAVE_DNSSEC) || defined(HAVE_CRYPTOHASH)
                     32: 
                     33: static const struct nettle_hash *hash;
                     34: static void *ctx;
                     35: static unsigned char *digest;
                     36: 
                     37: void hash_questions_init(void)
                     38: {
                     39:   if (!(hash = hash_find("sha256")))
                     40:     die(_("Failed to create SHA-256 hash object"), NULL, EC_MISC);
                     41: 
                     42:   ctx = safe_malloc(hash->context_size);
                     43:   digest = safe_malloc(hash->digest_size);
                     44: }
                     45: 
                     46: unsigned char *hash_questions(struct dns_header *header, size_t plen, char *name)
                     47: {
                     48:   int q;
                     49:   unsigned char *p = (unsigned char *)(header+1);
                     50: 
                     51:   hash->init(ctx);
                     52: 
                     53:   for (q = ntohs(header->qdcount); q != 0; q--) 
                     54:     {
                     55:       char *cp, c;
                     56: 
                     57:       if (!extract_name(header, plen, &p, name, 1, 4))
                     58:        return NULL; /* bad packet */
                     59: 
                     60:       for (cp = name; (c = *cp); cp++)
                     61:         if (c >= 'A' && c <= 'Z')
                     62:           *cp += 'a' - 'A';
                     63: 
                     64:       hash->update(ctx, cp - name, (unsigned char *)name);
                     65:       /* CRC the class and type as well */
                     66:       hash->update(ctx, 4, p);
                     67: 
                     68:       p += 4;
                     69:       if (!CHECK_LEN(header, p, plen, 0))
                     70:        return NULL; /* bad packet */
                     71:     }
                     72:   
                     73:   hash->digest(ctx, hash->digest_size, digest);
                     74:   return digest;
                     75: }
                     76: 
                     77: #else /* HAVE_DNSSEC  || HAVE_CRYPTOHASH */
                     78: 
                     79: #define SHA256_BLOCK_SIZE 32            /* SHA256 outputs a 32 byte digest */
                     80: typedef unsigned char BYTE;             /* 8-bit byte */
                     81: typedef unsigned int  WORD;             /* 32-bit word, change to "long" for 16-bit machines */
                     82: 
                     83: typedef struct {
                     84:   BYTE data[64];
                     85:   WORD datalen;
                     86:   unsigned long long bitlen;
                     87:   WORD state[8];
                     88: } SHA256_CTX;
                     89: 
                     90: static void sha256_init(SHA256_CTX *ctx);
                     91: static void sha256_update(SHA256_CTX *ctx, const BYTE data[], size_t len);
                     92: static void sha256_final(SHA256_CTX *ctx, BYTE hash[]);
                     93: 
                     94: void hash_questions_init(void)
                     95: {
                     96: }
                     97: 
                     98: unsigned char *hash_questions(struct dns_header *header, size_t plen, char *name)
                     99: {
                    100:   int q;
                    101:   unsigned char *p = (unsigned char *)(header+1);
                    102:   SHA256_CTX ctx;
                    103:   static BYTE digest[SHA256_BLOCK_SIZE];
                    104:   
                    105:   sha256_init(&ctx);
                    106:     
                    107:   for (q = ntohs(header->qdcount); q != 0; q--) 
                    108:     {
                    109:       char *cp, c;
                    110: 
                    111:       if (!extract_name(header, plen, &p, name, 1, 4))
                    112:        return NULL; /* bad packet */
                    113: 
                    114:       for (cp = name; (c = *cp); cp++)
                    115:         if (c >= 'A' && c <= 'Z')
                    116:           *cp += 'a' - 'A';
                    117: 
                    118:       sha256_update(&ctx, (BYTE *)name, cp - name);
                    119:       /* CRC the class and type as well */
                    120:       sha256_update(&ctx, (BYTE *)p, 4);
                    121: 
                    122:       p += 4;
                    123:       if (!CHECK_LEN(header, p, plen, 0))
                    124:        return NULL; /* bad packet */
                    125:     }
                    126:   
                    127:   sha256_final(&ctx, digest);
                    128:   return (unsigned char *)digest;
                    129: }
                    130: 
                    131: /* Code from here onwards comes from https://github.com/B-Con/crypto-algorithms
                    132:    and was written by Brad Conte (brad@bradconte.com), to whom all credit is given.
                    133: 
                    134:    This code is in the public domain, and the copyright notice at the head of this 
                    135:    file does not apply to it.
                    136: */
                    137: 
                    138: 
                    139: /****************************** MACROS ******************************/
                    140: #define ROTLEFT(a,b) (((a) << (b)) | ((a) >> (32-(b))))
                    141: #define ROTRIGHT(a,b) (((a) >> (b)) | ((a) << (32-(b))))
                    142: 
                    143: #define CH(x,y,z) (((x) & (y)) ^ (~(x) & (z)))
                    144: #define MAJ(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
                    145: #define EP0(x) (ROTRIGHT(x,2) ^ ROTRIGHT(x,13) ^ ROTRIGHT(x,22))
                    146: #define EP1(x) (ROTRIGHT(x,6) ^ ROTRIGHT(x,11) ^ ROTRIGHT(x,25))
                    147: #define SIG0(x) (ROTRIGHT(x,7) ^ ROTRIGHT(x,18) ^ ((x) >> 3))
                    148: #define SIG1(x) (ROTRIGHT(x,17) ^ ROTRIGHT(x,19) ^ ((x) >> 10))
                    149: 
                    150: /**************************** VARIABLES *****************************/
                    151: static const WORD k[64] = {
                    152:                           0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,
                    153:                           0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,
                    154:                           0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,
                    155:                           0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,
                    156:                           0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,
                    157:                           0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,
                    158:                           0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,
                    159:                           0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
                    160: };
                    161: 
                    162: /*********************** FUNCTION DEFINITIONS ***********************/
                    163: static void sha256_transform(SHA256_CTX *ctx, const BYTE data[])
                    164: {
                    165:   WORD a, b, c, d, e, f, g, h, i, j, t1, t2, m[64];
                    166:   
                    167:   for (i = 0, j = 0; i < 16; ++i, j += 4)
                    168:     m[i] = (data[j] << 24) | (data[j + 1] << 16) | (data[j + 2] << 8) | (data[j + 3]);
                    169:   for ( ; i < 64; ++i)
                    170:     m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16];
                    171: 
                    172:   a = ctx->state[0];
                    173:   b = ctx->state[1];
                    174:   c = ctx->state[2];
                    175:   d = ctx->state[3];
                    176:   e = ctx->state[4];
                    177:   f = ctx->state[5];
                    178:   g = ctx->state[6];
                    179:   h = ctx->state[7];
                    180: 
                    181:   for (i = 0; i < 64; ++i)
                    182:     {
                    183:       t1 = h + EP1(e) + CH(e,f,g) + k[i] + m[i];
                    184:       t2 = EP0(a) + MAJ(a,b,c);
                    185:       h = g;
                    186:       g = f;
                    187:       f = e;
                    188:       e = d + t1;
                    189:       d = c;
                    190:       c = b;
                    191:       b = a;
                    192:       a = t1 + t2;
                    193:     }
                    194:   
                    195:   ctx->state[0] += a;
                    196:   ctx->state[1] += b;
                    197:   ctx->state[2] += c;
                    198:   ctx->state[3] += d;
                    199:   ctx->state[4] += e;
                    200:   ctx->state[5] += f;
                    201:   ctx->state[6] += g;
                    202:   ctx->state[7] += h;
                    203: }
                    204: 
                    205: static void sha256_init(SHA256_CTX *ctx)
                    206: {
                    207:   ctx->datalen = 0;
                    208:   ctx->bitlen = 0;
                    209:   ctx->state[0] = 0x6a09e667;
                    210:   ctx->state[1] = 0xbb67ae85;
                    211:   ctx->state[2] = 0x3c6ef372;
                    212:   ctx->state[3] = 0xa54ff53a;
                    213:   ctx->state[4] = 0x510e527f;
                    214:   ctx->state[5] = 0x9b05688c;
                    215:   ctx->state[6] = 0x1f83d9ab;
                    216:   ctx->state[7] = 0x5be0cd19;
                    217: }
                    218: 
                    219: static void sha256_update(SHA256_CTX *ctx, const BYTE data[], size_t len)
                    220: {
                    221:   WORD i;
                    222:   
                    223:   for (i = 0; i < len; ++i)
                    224:     {
                    225:       ctx->data[ctx->datalen] = data[i];
                    226:       ctx->datalen++;
                    227:       if (ctx->datalen == 64) {
                    228:        sha256_transform(ctx, ctx->data);
                    229:        ctx->bitlen += 512;
                    230:        ctx->datalen = 0;
                    231:       }
                    232:     }
                    233: }
                    234: 
                    235: static void sha256_final(SHA256_CTX *ctx, BYTE hash[])
                    236: {
                    237:   WORD i;
                    238:   
                    239:   i = ctx->datalen;
                    240: 
                    241:   /* Pad whatever data is left in the buffer. */
                    242:   if (ctx->datalen < 56)
                    243:     {
                    244:       ctx->data[i++] = 0x80;
                    245:       while (i < 56)
                    246:        ctx->data[i++] = 0x00;
                    247:     }
                    248:   else
                    249:     {
                    250:       ctx->data[i++] = 0x80;
                    251:       while (i < 64)
                    252:        ctx->data[i++] = 0x00;
                    253:       sha256_transform(ctx, ctx->data);
                    254:       memset(ctx->data, 0, 56);
                    255:     }
                    256:   
                    257:   /* Append to the padding the total message's length in bits and transform. */
                    258:   ctx->bitlen += ctx->datalen * 8;
                    259:   ctx->data[63] = ctx->bitlen;
                    260:   ctx->data[62] = ctx->bitlen >> 8;
                    261:   ctx->data[61] = ctx->bitlen >> 16;
                    262:   ctx->data[60] = ctx->bitlen >> 24;
                    263:   ctx->data[59] = ctx->bitlen >> 32;
                    264:   ctx->data[58] = ctx->bitlen >> 40;
                    265:   ctx->data[57] = ctx->bitlen >> 48;
                    266:   ctx->data[56] = ctx->bitlen >> 56;
                    267:   sha256_transform(ctx, ctx->data);
                    268:   
                    269:   /* Since this implementation uses little endian byte ordering and SHA uses big endian,
                    270:      reverse all the bytes when copying the final state to the output hash. */
                    271:   for (i = 0; i < 4; ++i)
                    272:     {
                    273:       hash[i]      = (ctx->state[0] >> (24 - i * 8)) & 0x000000ff;
                    274:       hash[i + 4]  = (ctx->state[1] >> (24 - i * 8)) & 0x000000ff;
                    275:       hash[i + 8]  = (ctx->state[2] >> (24 - i * 8)) & 0x000000ff;
                    276:       hash[i + 12] = (ctx->state[3] >> (24 - i * 8)) & 0x000000ff;
                    277:       hash[i + 16] = (ctx->state[4] >> (24 - i * 8)) & 0x000000ff;
                    278:       hash[i + 20] = (ctx->state[5] >> (24 - i * 8)) & 0x000000ff;
                    279:       hash[i + 24] = (ctx->state[6] >> (24 - i * 8)) & 0x000000ff;
                    280:       hash[i + 28] = (ctx->state[7] >> (24 - i * 8)) & 0x000000ff;
                    281:     }
                    282: }
                    283: 
                    284: #endif

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