LCOV - code coverage report
Current view: top level - src/crypto - aes.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 112 112 100.0 %
Date: 2025-02-23 09:33:43 Functions: 28 28 100.0 %

          Line data    Source code
       1             : // Copyright (c) 2016 The Bitcoin Core developers
       2             : // Distributed under the MIT software license, see the accompanying
       3             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       4             : 
       5             : #include "aes.h"
       6             : #include "crypto/common.h"
       7             : 
       8             : #include <assert.h>
       9             : #include <string.h>
      10             : 
      11             : extern "C" {
      12             : #include "crypto/ctaes/ctaes.c"
      13             : }
      14             : 
      15          13 : AES128Encrypt::AES128Encrypt(const unsigned char key[16])
      16             : {
      17          13 :     AES128_init(&ctx, key);
      18          13 : }
      19             : 
      20          13 : AES128Encrypt::~AES128Encrypt()
      21             : {
      22          13 :     memset(&ctx, 0, sizeof(ctx));
      23          13 : }
      24             : 
      25          89 : void AES128Encrypt::Encrypt(unsigned char ciphertext[16], const unsigned char plaintext[16]) const
      26             : {
      27          89 :     AES128_encrypt(&ctx, 1, ciphertext, plaintext);
      28          89 : }
      29             : 
      30          13 : AES128Decrypt::AES128Decrypt(const unsigned char key[16])
      31             : {
      32          13 :     AES128_init(&ctx, key);
      33          13 : }
      34             : 
      35          13 : AES128Decrypt::~AES128Decrypt()
      36             : {
      37          13 :     memset(&ctx, 0, sizeof(ctx));
      38          13 : }
      39             : 
      40          89 : void AES128Decrypt::Decrypt(unsigned char plaintext[16], const unsigned char ciphertext[16]) const
      41             : {
      42          89 :     AES128_decrypt(&ctx, 1, plaintext, ciphertext);
      43          89 : }
      44             : 
      45        7011 : AES256Encrypt::AES256Encrypt(const unsigned char key[32])
      46             : {
      47        7011 :     AES256_init(&ctx, key);
      48        7011 : }
      49             : 
      50        7011 : AES256Encrypt::~AES256Encrypt()
      51             : {
      52        7011 :     memset(&ctx, 0, sizeof(ctx));
      53        7011 : }
      54             : 
      55       15459 : void AES256Encrypt::Encrypt(unsigned char ciphertext[16], const unsigned char plaintext[16]) const
      56             : {
      57       15459 :     AES256_encrypt(&ctx, 1, ciphertext, plaintext);
      58       15459 : }
      59             : 
      60        8415 : AES256Decrypt::AES256Decrypt(const unsigned char key[32])
      61             : {
      62        8415 :     AES256_init(&ctx, key);
      63        8415 : }
      64             : 
      65        8415 : AES256Decrypt::~AES256Decrypt()
      66             : {
      67        8415 :     memset(&ctx, 0, sizeof(ctx));
      68        8415 : }
      69             : 
      70       19633 : void AES256Decrypt::Decrypt(unsigned char plaintext[16], const unsigned char ciphertext[16]) const
      71             : {
      72       19633 :     AES256_decrypt(&ctx, 1, plaintext, ciphertext);
      73       19633 : }
      74             : 
      75             : 
      76             : template <typename T>
      77        7269 : static int CBCEncrypt(const T& enc, const unsigned char iv[AES_BLOCKSIZE], const unsigned char* data, int size, bool pad, unsigned char* out)
      78             : {
      79        7269 :     int written = 0;
      80        7269 :     int padsize = size % AES_BLOCKSIZE;
      81             :     unsigned char mixed[AES_BLOCKSIZE];
      82             : 
      83        7269 :     if (!data || !size || !out)
      84             :         return 0;
      85             : 
      86        7269 :     if (!pad && padsize != 0)
      87             :         return 0;
      88             : 
      89       17357 :     memcpy(mixed, iv, AES_BLOCKSIZE);
      90             : 
      91             :     // Write all but the last block
      92       17357 :     while (written + AES_BLOCKSIZE <= size) {
      93      173553 :         for (int i = 0; i != AES_BLOCKSIZE; i++)
      94      163344 :             mixed[i] ^= *data++;
      95       10209 :         enc.Encrypt(out + written, mixed);
      96       10209 :         memcpy(mixed, out + written, AES_BLOCKSIZE);
      97       10209 :         written += AES_BLOCKSIZE;
      98             :     }
      99        7148 :     if (pad) {
     100             :         // For all that remains, pad each byte with the value of the remaining
     101             :         // space. If there is none, pad by a full block.
     102       31463 :         for (int i = 0; i != padsize; i++)
     103       26136 :             mixed[i] ^= *data++;
     104       64423 :         for (int i = padsize; i != AES_BLOCKSIZE; i++)
     105       59096 :             mixed[i] ^= AES_BLOCKSIZE - padsize;
     106        5327 :         enc.Encrypt(out + written, mixed);
     107        5327 :         written += AES_BLOCKSIZE;
     108             :     }
     109             :     return written;
     110             : }
     111             : 
     112             : template <typename T>
     113        8552 : static int CBCDecrypt(const T& dec, const unsigned char iv[AES_BLOCKSIZE], const unsigned char* data, int size, bool pad, unsigned char* out)
     114             : {
     115        8552 :     unsigned char padsize = 0;
     116        8552 :     int written = 0;
     117        8552 :     bool fail = false;
     118        8552 :     const unsigned char* prev = iv;
     119             : 
     120        8552 :     if (!data || !size || !out)
     121             :         return 0;
     122             : 
     123        8552 :     if (size % AES_BLOCKSIZE != 0)
     124             :         return 0;
     125             : 
     126             :     // Decrypt all data. Padding will be checked in the output.
     127       28262 :     while (written != size) {
     128       19710 :         dec.Decrypt(out, data + written);
     129      335070 :         for (int i = 0; i != AES_BLOCKSIZE; i++)
     130      315360 :             *out++ ^= prev[i];
     131       19710 :         prev = data + written;
     132       19710 :         written += AES_BLOCKSIZE;
     133             :     }
     134             : 
     135             :     // When decrypting padding, attempt to run in constant-time
     136        8552 :     if (pad) {
     137             :         // If used, padding size is the value of the last decrypted byte. For
     138             :         // it to be valid, It must be between 1 and AES_BLOCKSIZE.
     139        6746 :         padsize = *--out;
     140        6746 :         fail = !padsize | (padsize > AES_BLOCKSIZE);
     141             : 
     142             :         // If not well-formed, treat it as though there's no padding.
     143        6746 :         padsize *= !fail;
     144             : 
     145             :         // All padding must equal the last byte otherwise it's not well-formed
     146      114682 :         for (int i = AES_BLOCKSIZE; i != 0; i--)
     147      107936 :             fail |= ((i > AES_BLOCKSIZE - padsize) & (*out-- != padsize));
     148             : 
     149        6746 :         written -= padsize;
     150             :     }
     151        8552 :     return written * !fail;
     152             : }
     153             : 
     154        7005 : AES256CBCEncrypt::AES256CBCEncrypt(const unsigned char key[AES256_KEYSIZE], const unsigned char ivIn[AES_BLOCKSIZE], bool padIn)
     155        7005 :     : enc(key), pad(padIn)
     156             : {
     157        7005 :     memcpy(iv, ivIn, AES_BLOCKSIZE);
     158        7005 : }
     159             : 
     160        7133 : int AES256CBCEncrypt::Encrypt(const unsigned char* data, int size, unsigned char* out) const
     161             : {
     162        7133 :     return CBCEncrypt(enc, iv, data, size, pad, out);
     163             : }
     164             : 
     165       14010 : AES256CBCEncrypt::~AES256CBCEncrypt()
     166             : {
     167        7005 :     memset(iv, 0, sizeof(iv));
     168        7005 : }
     169             : 
     170        8408 : AES256CBCDecrypt::AES256CBCDecrypt(const unsigned char key[AES256_KEYSIZE], const unsigned char ivIn[AES_BLOCKSIZE], bool padIn)
     171        8408 :     : dec(key), pad(padIn)
     172             : {
     173        8408 :     memcpy(iv, ivIn, AES_BLOCKSIZE);
     174        8408 : }
     175             : 
     176             : 
     177        8476 : int AES256CBCDecrypt::Decrypt(const unsigned char* data, int size, unsigned char* out) const
     178             : {
     179        8476 :     return CBCDecrypt(dec, iv, data, size, pad, out);
     180             : }
     181             : 
     182       16816 : AES256CBCDecrypt::~AES256CBCDecrypt()
     183             : {
     184        8408 :     memset(iv, 0, sizeof(iv));
     185        8408 : }
     186             : 
     187           8 : AES128CBCEncrypt::AES128CBCEncrypt(const unsigned char key[AES128_KEYSIZE], const unsigned char ivIn[AES_BLOCKSIZE], bool padIn)
     188           8 :     : enc(key), pad(padIn)
     189             : {
     190           8 :     memcpy(iv, ivIn, AES_BLOCKSIZE);
     191           8 : }
     192             : 
     193          16 : AES128CBCEncrypt::~AES128CBCEncrypt()
     194             : {
     195           8 :     memset(iv, 0, AES_BLOCKSIZE);
     196           8 : }
     197             : 
     198         136 : int AES128CBCEncrypt::Encrypt(const unsigned char* data, int size, unsigned char* out) const
     199             : {
     200         136 :     return CBCEncrypt(enc, iv, data, size, pad, out);
     201             : }
     202             : 
     203           8 : AES128CBCDecrypt::AES128CBCDecrypt(const unsigned char key[AES128_KEYSIZE], const unsigned char ivIn[AES_BLOCKSIZE], bool padIn)
     204           8 :     : dec(key), pad(padIn)
     205             : {
     206           8 :     memcpy(iv, ivIn, AES_BLOCKSIZE);
     207           8 : }
     208             : 
     209          16 : AES128CBCDecrypt::~AES128CBCDecrypt()
     210             : {
     211           8 :     memset(iv, 0, AES_BLOCKSIZE);
     212           8 : }
     213             : 
     214          76 : int AES128CBCDecrypt::Decrypt(const unsigned char* data, int size, unsigned char* out) const
     215             : {
     216          76 :     return CBCDecrypt(dec, iv, data, size, pad, out);
     217             : }

Generated by: LCOV version 1.14