LCOV - code coverage report
Current view: top level - contrib/pgcrypto - px-hmac.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 86.1 % 72 62
Test Date: 2026-03-04 08:14:57 Functions: 75.0 % 8 6
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*
       2              :  * px-hmac.c
       3              :  *      HMAC implementation.
       4              :  *
       5              :  * Copyright (c) 2001 Marko Kreen
       6              :  * All rights reserved.
       7              :  *
       8              :  * Redistribution and use in source and binary forms, with or without
       9              :  * modification, are permitted provided that the following conditions
      10              :  * are met:
      11              :  * 1. Redistributions of source code must retain the above copyright
      12              :  *    notice, this list of conditions and the following disclaimer.
      13              :  * 2. Redistributions in binary form must reproduce the above copyright
      14              :  *    notice, this list of conditions and the following disclaimer in the
      15              :  *    documentation and/or other materials provided with the distribution.
      16              :  *
      17              :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
      18              :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      19              :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      20              :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
      21              :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      22              :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      23              :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      24              :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      25              :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      26              :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      27              :  * SUCH DAMAGE.
      28              :  *
      29              :  * contrib/pgcrypto/px-hmac.c
      30              :  */
      31              : 
      32              : #include "postgres.h"
      33              : 
      34              : #include "px.h"
      35              : 
      36              : #define HMAC_IPAD 0x36
      37              : #define HMAC_OPAD 0x5C
      38              : 
      39              : static unsigned
      40           14 : hmac_result_size(PX_HMAC *h)
      41              : {
      42           14 :     return px_md_result_size(h->md);
      43              : }
      44              : 
      45              : static unsigned
      46            0 : hmac_block_size(PX_HMAC *h)
      47              : {
      48            0 :     return px_md_block_size(h->md);
      49              : }
      50              : 
      51              : static void
      52           14 : hmac_init(PX_HMAC *h, const uint8 *key, unsigned klen)
      53              : {
      54              :     unsigned    bs,
      55              :                 i;
      56              :     uint8      *keybuf;
      57           14 :     PX_MD      *md = h->md;
      58              : 
      59           14 :     bs = px_md_block_size(md);
      60           14 :     keybuf = palloc0(bs);
      61              : 
      62           14 :     if (klen > bs)
      63              :     {
      64            4 :         px_md_update(md, key, klen);
      65            4 :         px_md_finish(md, keybuf);
      66            4 :         px_md_reset(md);
      67              :     }
      68              :     else
      69           10 :         memcpy(keybuf, key, klen);
      70              : 
      71          910 :     for (i = 0; i < bs; i++)
      72              :     {
      73          896 :         h->p.ipad[i] = keybuf[i] ^ HMAC_IPAD;
      74          896 :         h->p.opad[i] = keybuf[i] ^ HMAC_OPAD;
      75              :     }
      76              : 
      77           14 :     px_memset(keybuf, 0, bs);
      78           14 :     pfree(keybuf);
      79              : 
      80           14 :     px_md_update(md, h->p.ipad, bs);
      81           14 : }
      82              : 
      83              : static void
      84            0 : hmac_reset(PX_HMAC *h)
      85              : {
      86            0 :     PX_MD      *md = h->md;
      87            0 :     unsigned    bs = px_md_block_size(md);
      88              : 
      89            0 :     px_md_reset(md);
      90            0 :     px_md_update(md, h->p.ipad, bs);
      91            0 : }
      92              : 
      93              : static void
      94           14 : hmac_update(PX_HMAC *h, const uint8 *data, unsigned dlen)
      95              : {
      96           14 :     px_md_update(h->md, data, dlen);
      97           14 : }
      98              : 
      99              : static void
     100           14 : hmac_finish(PX_HMAC *h, uint8 *dst)
     101              : {
     102           14 :     PX_MD      *md = h->md;
     103              :     unsigned    bs,
     104              :                 hlen;
     105              :     uint8      *buf;
     106              : 
     107           14 :     bs = px_md_block_size(md);
     108           14 :     hlen = px_md_result_size(md);
     109              : 
     110           14 :     buf = palloc(hlen);
     111              : 
     112           14 :     px_md_finish(md, buf);
     113              : 
     114           14 :     px_md_reset(md);
     115           14 :     px_md_update(md, h->p.opad, bs);
     116           14 :     px_md_update(md, buf, hlen);
     117           14 :     px_md_finish(md, dst);
     118              : 
     119           14 :     px_memset(buf, 0, hlen);
     120           14 :     pfree(buf);
     121           14 : }
     122              : 
     123              : static void
     124           14 : hmac_free(PX_HMAC *h)
     125              : {
     126              :     unsigned    bs;
     127              : 
     128           14 :     bs = px_md_block_size(h->md);
     129           14 :     px_md_free(h->md);
     130              : 
     131           14 :     px_memset(h->p.ipad, 0, bs);
     132           14 :     px_memset(h->p.opad, 0, bs);
     133           14 :     pfree(h->p.ipad);
     134           14 :     pfree(h->p.opad);
     135           14 :     pfree(h);
     136           14 : }
     137              : 
     138              : 
     139              : /* PUBLIC FUNCTIONS */
     140              : 
     141              : int
     142           15 : px_find_hmac(const char *name, PX_HMAC **res)
     143              : {
     144              :     int         err;
     145              :     PX_MD      *md;
     146              :     PX_HMAC    *h;
     147              :     unsigned    bs;
     148              : 
     149           15 :     err = px_find_digest(name, &md);
     150           15 :     if (err)
     151            1 :         return err;
     152              : 
     153           14 :     bs = px_md_block_size(md);
     154           14 :     if (bs < 2)
     155              :     {
     156            0 :         px_md_free(md);
     157            0 :         return PXE_HASH_UNUSABLE_FOR_HMAC;
     158              :     }
     159              : 
     160           14 :     h = palloc_object(PX_HMAC);
     161           14 :     h->p.ipad = palloc(bs);
     162           14 :     h->p.opad = palloc(bs);
     163           14 :     h->md = md;
     164              : 
     165           14 :     h->result_size = hmac_result_size;
     166           14 :     h->block_size = hmac_block_size;
     167           14 :     h->reset = hmac_reset;
     168           14 :     h->update = hmac_update;
     169           14 :     h->finish = hmac_finish;
     170           14 :     h->free = hmac_free;
     171           14 :     h->init = hmac_init;
     172              : 
     173           14 :     *res = h;
     174              : 
     175           14 :     return 0;
     176              : }
        

Generated by: LCOV version 2.0-1