LCOV - code coverage report
Current view: top level - src/common - checksum_helper.c (source / functions) Hit Total Coverage
Test: PostgreSQL 14devel Lines: 97 102 95.1 %
Date: 2020-07-11 21:06:30 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * checksum_helper.c
       4             :  *    Compute a checksum of any of various types using common routines
       5             :  *
       6             :  * Portions Copyright (c) 2016-2020, PostgreSQL Global Development Group
       7             :  *
       8             :  * IDENTIFICATION
       9             :  *        src/common/checksum_helper.c
      10             :  *
      11             :  *-------------------------------------------------------------------------
      12             :  */
      13             : 
      14             : #ifndef FRONTEND
      15             : #include "postgres.h"
      16             : #else
      17             : #include "postgres_fe.h"
      18             : #endif
      19             : 
      20             : #include "common/checksum_helper.h"
      21             : 
      22             : /*
      23             :  * If 'name' is a recognized checksum type, set *type to the corresponding
      24             :  * constant and return true. Otherwise, set *type to CHECKSUM_TYPE_NONE and
      25             :  * return false.
      26             :  */
      27             : bool
      28       76694 : pg_checksum_parse_type(char *name, pg_checksum_type *type)
      29             : {
      30       76694 :     pg_checksum_type result_type = CHECKSUM_TYPE_NONE;
      31       76694 :     bool        result = true;
      32             : 
      33       76694 :     if (pg_strcasecmp(name, "none") == 0)
      34           2 :         result_type = CHECKSUM_TYPE_NONE;
      35       76692 :     else if (pg_strcasecmp(name, "crc32c") == 0)
      36       69208 :         result_type = CHECKSUM_TYPE_CRC32C;
      37        7484 :     else if (pg_strcasecmp(name, "sha224") == 0)
      38        1870 :         result_type = CHECKSUM_TYPE_SHA224;
      39        5614 :     else if (pg_strcasecmp(name, "sha256") == 0)
      40        1870 :         result_type = CHECKSUM_TYPE_SHA256;
      41        3744 :     else if (pg_strcasecmp(name, "sha384") == 0)
      42        1870 :         result_type = CHECKSUM_TYPE_SHA384;
      43        1874 :     else if (pg_strcasecmp(name, "sha512") == 0)
      44        1870 :         result_type = CHECKSUM_TYPE_SHA512;
      45             :     else
      46           4 :         result = false;
      47             : 
      48       76694 :     *type = result_type;
      49       76694 :     return result;
      50             : }
      51             : 
      52             : /*
      53             :  * Get the canonical human-readable name corresponding to a checksum type.
      54             :  */
      55             : char *
      56      126672 : pg_checksum_type_name(pg_checksum_type type)
      57             : {
      58      126672 :     switch (type)
      59             :     {
      60           0 :         case CHECKSUM_TYPE_NONE:
      61           0 :             return "NONE";
      62      119200 :         case CHECKSUM_TYPE_CRC32C:
      63      119200 :             return "CRC32C";
      64        1868 :         case CHECKSUM_TYPE_SHA224:
      65        1868 :             return "SHA224";
      66        1868 :         case CHECKSUM_TYPE_SHA256:
      67        1868 :             return "SHA256";
      68        1868 :         case CHECKSUM_TYPE_SHA384:
      69        1868 :             return "SHA384";
      70        1868 :         case CHECKSUM_TYPE_SHA512:
      71        1868 :             return "SHA512";
      72             :     }
      73             : 
      74             :     Assert(false);
      75           0 :     return "???";
      76             : }
      77             : 
      78             : /*
      79             :  * Initialize a checksum context for checksums of the given type.
      80             :  */
      81             : void
      82      195918 : pg_checksum_init(pg_checksum_context *context, pg_checksum_type type)
      83             : {
      84      195918 :     context->type = type;
      85             : 
      86      195918 :     switch (type)
      87             :     {
      88        3738 :         case CHECKSUM_TYPE_NONE:
      89             :             /* do nothing */
      90        3738 :             break;
      91      177244 :         case CHECKSUM_TYPE_CRC32C:
      92      177244 :             INIT_CRC32C(context->raw_context.c_crc32c);
      93      177244 :             break;
      94        3734 :         case CHECKSUM_TYPE_SHA224:
      95        3734 :             pg_sha224_init(&context->raw_context.c_sha224);
      96        3734 :             break;
      97        3734 :         case CHECKSUM_TYPE_SHA256:
      98        3734 :             pg_sha256_init(&context->raw_context.c_sha256);
      99        3734 :             break;
     100        3734 :         case CHECKSUM_TYPE_SHA384:
     101        3734 :             pg_sha384_init(&context->raw_context.c_sha384);
     102        3734 :             break;
     103        3734 :         case CHECKSUM_TYPE_SHA512:
     104        3734 :             pg_sha512_init(&context->raw_context.c_sha512);
     105        3734 :             break;
     106             :     }
     107      195918 : }
     108             : 
     109             : /*
     110             :  * Update a checksum context with new data.
     111             :  */
     112             : void
     113      568110 : pg_checksum_update(pg_checksum_context *context, const uint8 *input,
     114             :                    size_t len)
     115             : {
     116      568110 :     switch (context->type)
     117             :     {
     118        4660 :         case CHECKSUM_TYPE_NONE:
     119             :             /* do nothing */
     120        4660 :             break;
     121      507826 :         case CHECKSUM_TYPE_CRC32C:
     122      507826 :             COMP_CRC32C(context->raw_context.c_crc32c, input, len);
     123      507826 :             break;
     124       13906 :         case CHECKSUM_TYPE_SHA224:
     125       13906 :             pg_sha224_update(&context->raw_context.c_sha224, input, len);
     126       13906 :             break;
     127       13906 :         case CHECKSUM_TYPE_SHA256:
     128       13906 :             pg_sha256_update(&context->raw_context.c_sha256, input, len);
     129       13906 :             break;
     130       13906 :         case CHECKSUM_TYPE_SHA384:
     131       13906 :             pg_sha384_update(&context->raw_context.c_sha384, input, len);
     132       13906 :             break;
     133       13906 :         case CHECKSUM_TYPE_SHA512:
     134       13906 :             pg_sha512_update(&context->raw_context.c_sha512, input, len);
     135       13906 :             break;
     136             :     }
     137      568110 : }
     138             : 
     139             : /*
     140             :  * Finalize a checksum computation and write the result to an output buffer.
     141             :  *
     142             :  * The caller must ensure that the buffer is at least PG_CHECKSUM_MAX_LENGTH
     143             :  * bytes in length. The return value is the number of bytes actually written.
     144             :  */
     145             : int
     146      192174 : pg_checksum_final(pg_checksum_context *context, uint8 *output)
     147             : {
     148      192174 :     int         retval = 0;
     149             : 
     150             :     StaticAssertStmt(sizeof(pg_crc32c) <= PG_CHECKSUM_MAX_LENGTH,
     151             :                      "CRC-32C digest too big for PG_CHECKSUM_MAX_LENGTH");
     152             :     StaticAssertStmt(PG_SHA224_DIGEST_LENGTH <= PG_CHECKSUM_MAX_LENGTH,
     153             :                      "SHA224 digest too for PG_CHECKSUM_MAX_LENGTH");
     154             :     StaticAssertStmt(PG_SHA256_DIGEST_LENGTH <= PG_CHECKSUM_MAX_LENGTH,
     155             :                      "SHA256 digest too for PG_CHECKSUM_MAX_LENGTH");
     156             :     StaticAssertStmt(PG_SHA384_DIGEST_LENGTH <= PG_CHECKSUM_MAX_LENGTH,
     157             :                      "SHA384 digest too for PG_CHECKSUM_MAX_LENGTH");
     158             :     StaticAssertStmt(PG_SHA512_DIGEST_LENGTH <= PG_CHECKSUM_MAX_LENGTH,
     159             :                      "SHA512 digest too for PG_CHECKSUM_MAX_LENGTH");
     160             : 
     161      192174 :     switch (context->type)
     162             :     {
     163           0 :         case CHECKSUM_TYPE_NONE:
     164           0 :             break;
     165      177238 :         case CHECKSUM_TYPE_CRC32C:
     166      177238 :             FIN_CRC32C(context->raw_context.c_crc32c);
     167      177238 :             retval = sizeof(pg_crc32c);
     168      177238 :             memcpy(output, &context->raw_context.c_crc32c, retval);
     169      177238 :             break;
     170        3734 :         case CHECKSUM_TYPE_SHA224:
     171        3734 :             pg_sha224_final(&context->raw_context.c_sha224, output);
     172        3734 :             retval = PG_SHA224_DIGEST_LENGTH;
     173        3734 :             break;
     174        3734 :         case CHECKSUM_TYPE_SHA256:
     175        3734 :             pg_sha256_final(&context->raw_context.c_sha256, output);
     176        3734 :             retval = PG_SHA256_DIGEST_LENGTH;
     177        3734 :             break;
     178        3734 :         case CHECKSUM_TYPE_SHA384:
     179        3734 :             pg_sha384_final(&context->raw_context.c_sha384, output);
     180        3734 :             retval = PG_SHA384_DIGEST_LENGTH;
     181        3734 :             break;
     182        3734 :         case CHECKSUM_TYPE_SHA512:
     183        3734 :             pg_sha512_final(&context->raw_context.c_sha512, output);
     184        3734 :             retval = PG_SHA512_DIGEST_LENGTH;
     185        3734 :             break;
     186             :     }
     187             : 
     188      192174 :     Assert(retval <= PG_CHECKSUM_MAX_LENGTH);
     189      192174 :     return retval;
     190             : }

Generated by: LCOV version 1.13