LCOV - code coverage report
Current view: top level - core/core/string - SPCoreCrypto.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 66 69 95.7 %
Date: 2024-05-12 00:16:13 Functions: 25 28 89.3 %

          Line data    Source code
       1             : /**
       2             : Copyright (c) 2021-2022 Roman Katuntsev <sbkarr@stappler.org>
       3             : Copyright (c) 2023-2924 Stappler LLC <admin@stappler.dev>
       4             : 
       5             : Permission is hereby granted, free of charge, to any person obtaining a copy
       6             : of this software and associated documentation files (the "Software"), to deal
       7             : in the Software without restriction, including without limitation the rights
       8             : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
       9             : copies of the Software, and to permit persons to whom the Software is
      10             : furnished to do so, subject to the following conditions:
      11             : 
      12             : The above copyright notice and this permission notice shall be included in
      13             : all copies or substantial portions of the Software.
      14             : 
      15             : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      16             : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      17             : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      18             : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      19             : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      20             : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
      21             : THE SOFTWARE.
      22             : **/
      23             : 
      24             : #ifndef STAPPLER_CORE_STRING_SPCRYPTO_H_
      25             : #define STAPPLER_CORE_STRING_SPCRYPTO_H_
      26             : 
      27             : #include "SPIO.h"
      28             : #include "SPBytesView.h"
      29             : 
      30             : namespace STAPPLER_VERSIONIZED stappler {
      31             : 
      32             : struct CoderSource {
      33             :         CoderSource(const uint8_t *d, size_t len);
      34             :         CoderSource(const char *d, size_t len);
      35             :         CoderSource(const char *d);
      36             :         CoderSource(const StringView &d);
      37             : 
      38             :         CoderSource(const typename memory::PoolInterface::BytesType &d);
      39             :         CoderSource(const typename memory::StandartInterface::BytesType &d);
      40             : 
      41             :         CoderSource(const typename memory::PoolInterface::StringType &d);
      42             :         CoderSource(const typename memory::StandartInterface::StringType &d);
      43             : 
      44             :         template <Endian Order>
      45             :         CoderSource(const BytesViewTemplate<Order> &d);
      46             : 
      47             :         CoderSource(const BytesReader<uint8_t> &d);
      48             :         CoderSource(const BytesReader<char> &d);
      49             : 
      50             :         template <size_t Size>
      51             :         CoderSource(const std::array<uint8_t, Size> &d);
      52             : 
      53             :         CoderSource();
      54             : 
      55             :         CoderSource(const CoderSource &) = delete;
      56             :         CoderSource(CoderSource &&) = delete;
      57             : 
      58             :         CoderSource& operator=(const CoderSource &) = delete;
      59             :         CoderSource& operator=(CoderSource &&) = delete;
      60             : 
      61             :         BytesViewTemplate<Endian::Network> _data;
      62             :         size_t _offset = 0;
      63             : 
      64             :         const uint8_t *data() const;
      65             :         size_t size() const;
      66             :         bool empty() const;
      67             : 
      68             :         BytesViewTemplate<Endian::Network> view() const;
      69             : 
      70             :         uint8_t operator[] (size_t s) const;
      71             : 
      72             :         size_t read(uint8_t *buf, size_t nbytes);
      73             :         size_t seek(int64_t offset, io::Seek s);
      74             :         size_t tell() const;
      75             : };
      76             : 
      77             : }
      78             : 
      79             : 
      80             : namespace STAPPLER_VERSIONIZED stappler::crypto {
      81             : 
      82             : constexpr uint8_t HMAC_I_PAD = 0x36;
      83             : constexpr uint8_t HMAC_O_PAD = 0x5C;
      84             : 
      85             : #ifndef SP_SECURE_KEY
      86             : constexpr auto SP_SECURE_KEY = "Nev3rseenany0nesoequalinth1sscale";
      87             : #endif
      88             : 
      89             : /* SHA-1 160-bit context
      90             :  * designed for chain use: Sha1().update(input).final() */
      91             : struct Sha1 {
      92             :         struct _Ctx {
      93             :                 uint32_t digest[5];
      94             :                 uint32_t count_lo, count_hi;
      95             :                 uint32_t data[16];
      96             :                 int32_t local;
      97             :         };
      98             : 
      99             :         constexpr static uint32_t Length = 20;
     100             :         using Buf = std::array<uint8_t, Length>;
     101             : 
     102             :         static Buf make(const CoderSource &, const StringView &salt = StringView());
     103             :         static Buf hmac(const CoderSource &data, const CoderSource &key);
     104             : 
     105             :         template <typename ... Args>
     106             :         static Buf perform(Args && ... args);
     107             : 
     108             :         Sha1();
     109             :         Sha1 & init();
     110             : 
     111             :         Sha1 & update(const uint8_t *, size_t);
     112             :         Sha1 & update(const CoderSource &);
     113             : 
     114             :         template  <typename T, typename ... Args>
     115             :         void _update(T && t, Args && ... args);
     116             : 
     117             :         template  <typename T>
     118             :         void _update(T && t);
     119             : 
     120             :         Buf final();
     121             :         void final(uint8_t *);
     122             : 
     123             :         _Ctx ctx;
     124             : };
     125             : 
     126             : /* SHA-2 512-bit context
     127             :  * designed for chain use: Sha512().update(input).final() */
     128             : struct Sha512 {
     129             :         struct _Ctx {
     130             :                 uint64_t length;
     131             :                 uint64_t state[8];
     132             :                 uint32_t curlen;
     133             :                 uint8_t buf[128];
     134             :         };
     135             : 
     136             :         constexpr static uint32_t Length = 64;
     137             :         using Buf = std::array<uint8_t, Length>;
     138             : 
     139             :         static Buf make(const CoderSource &, const StringView &salt = StringView());
     140             :         static Buf hmac(const CoderSource &data, const CoderSource &key);
     141             : 
     142             :         template <typename ... Args>
     143             :         static Buf perform(Args && ... args);
     144             : 
     145             :         Sha512();
     146             :         Sha512 & init();
     147             : 
     148             :         Sha512 & update(const uint8_t *, size_t);
     149             :         Sha512 & update(const CoderSource &);
     150             : 
     151             :         template  <typename T, typename ... Args>
     152             :         void _update(T && t, Args && ... args);
     153             : 
     154             :         template  <typename T>
     155             :         void _update(T && t);
     156             : 
     157             :         Buf final();
     158             :         void final(uint8_t *);
     159             : 
     160             :         _Ctx ctx;
     161             : };
     162             : 
     163             : /* SHA-2 256-bit context
     164             :  * designed for chain use: Sha256().update(input).final() */
     165             : struct Sha256 {
     166             :         struct _Ctx {
     167             :                 uint64_t length;
     168             :                 uint32_t state[8];
     169             :                 uint32_t curlen;
     170             :                 uint8_t buf[64];
     171             :         };
     172             : 
     173             :         constexpr static uint32_t Length = 32;
     174             :         using Buf = std::array<uint8_t, Length>;
     175             : 
     176             :         static Buf make(const CoderSource &, const StringView &salt = StringView());
     177             :         static Buf hmac(const CoderSource &data, const CoderSource &key);
     178             : 
     179             :         template <typename ... Args>
     180             :         static Buf perform(Args && ... args);
     181             : 
     182             :         Sha256();
     183             :         Sha256 & init();
     184             : 
     185             :         Sha256 & update(const uint8_t *, size_t);
     186             :         Sha256 & update(const CoderSource &);
     187             : 
     188             :         template  <typename T, typename ... Args>
     189             :         void _update(T && t, Args && ... args);
     190             : 
     191             :         template  <typename T>
     192             :         void _update(T && t);
     193             : 
     194             :         Buf final();
     195             :         void final(uint8_t *);
     196             : 
     197             :         _Ctx ctx;
     198             : };
     199             : 
     200             : union alignas(16) uint512_u {
     201             :     unsigned long long QWORD[8];
     202             :     unsigned char B[64];
     203             : };
     204             : 
     205             : /* GOST R 34.11-2012 hash context */
     206             : struct Gost3411_Ctx {
     207             :     uint512_u buffer;
     208             :     uint512_u h;
     209             :     uint512_u N;
     210             :     uint512_u Sigma;
     211             :     size_t bufsize;
     212             :     unsigned int digest_size;
     213             : };
     214             : 
     215             : struct Gost3411_512 {
     216             :         using _Ctx = Gost3411_Ctx;
     217             : 
     218             :         constexpr static uint32_t Length = 64;
     219             :         using Buf = std::array<uint8_t, Length>;
     220             : 
     221             :         template <typename ... Args>
     222             :         static Buf perform(Args && ... args);
     223             : 
     224             :         static Buf make(const CoderSource &, const StringView &salt = StringView());
     225             :         static Buf hmac(const CoderSource &data, const CoderSource &key);
     226             : 
     227             :         Gost3411_512();
     228             :         Gost3411_512 & init();
     229             : 
     230             :         Gost3411_512 & update(const uint8_t *, size_t);
     231             :         Gost3411_512 & update(const CoderSource &);
     232             : 
     233             :         template  <typename T, typename ... Args>
     234             :         void _update(T && t, Args && ... args);
     235             : 
     236             :         template  <typename T>
     237             :         void _update(T && t);
     238             : 
     239             :         Buf final();
     240             :         void final(uint8_t *);
     241             : 
     242             :         _Ctx ctx;
     243             : };
     244             : 
     245             : struct Gost3411_256 {
     246             :         using _Ctx = Gost3411_Ctx;
     247             : 
     248             :         constexpr static uint32_t Length = 32;
     249             :         using Buf = std::array<uint8_t, Length>;
     250             : 
     251             :         template <typename ... Args>
     252             :         static Buf perform(Args && ... args);
     253             : 
     254             :         static Buf make(const CoderSource &, const StringView &salt = StringView());
     255             :         static Buf hmac(const CoderSource &data, const CoderSource &key);
     256             : 
     257             :         Gost3411_256();
     258             :         Gost3411_256 & init();
     259             : 
     260             :         Gost3411_256 & update(const uint8_t *, size_t);
     261             :         Gost3411_256 & update(const CoderSource &);
     262             : 
     263             :         template  <typename T, typename ... Args>
     264             :         void _update(T && t, Args && ... args);
     265             : 
     266             :         template  <typename T>
     267             :         void _update(T && t);
     268             : 
     269             :         Buf final();
     270             :         void final(uint8_t *);
     271             : 
     272             :         _Ctx ctx;
     273             : };
     274             : 
     275             : } // namespace stappler::crypto
     276             : 
     277             : 
     278             : namespace STAPPLER_VERSIONIZED stappler {
     279             : 
     280       18041 : inline CoderSource::CoderSource(const uint8_t *d, size_t len)
     281       18041 : : _data(d, len) { }
     282             : 
     283          50 : inline CoderSource::CoderSource(const char *d, size_t len)
     284          50 : : _data((uint8_t *)d, len) { }
     285             : 
     286        1575 : inline CoderSource::CoderSource(const char *d)
     287        1575 : : _data((uint8_t *)d, strlen(d)) { }
     288             : 
     289        8125 : inline CoderSource::CoderSource(const StringView &d)
     290        8125 : : _data((uint8_t *)d.data(), d.size()) { }
     291             : 
     292        5675 : inline CoderSource::CoderSource(const typename memory::PoolInterface::BytesType &d)
     293        5675 : : _data(d.data(), d.size()) { }
     294             : 
     295        3925 : inline CoderSource::CoderSource(const typename memory::StandartInterface::BytesType &d)
     296        3925 : : _data(d.data(), d.size()) { }
     297             : 
     298         525 : inline CoderSource::CoderSource(const typename memory::PoolInterface::StringType &d)
     299         525 : : _data((const uint8_t *)d.data(), d.size()) { }
     300             : 
     301        1000 : inline CoderSource::CoderSource(const typename memory::StandartInterface::StringType &d)
     302        1000 : : _data((const uint8_t *)d.data(), d.size()) { }
     303             : 
     304             : template <Endian Order>
     305        7052 : inline CoderSource::CoderSource(const BytesViewTemplate<Order> &d)
     306        7052 : : _data(d.data(), d.size()) { }
     307             : 
     308             : inline CoderSource::CoderSource(const BytesReader<uint8_t> &d)
     309             : : _data(d.data(), d.size()) { }
     310             : 
     311             : inline CoderSource::CoderSource(const BytesReader<char> &d)
     312             : : _data((const uint8_t *)d.data(), d.size()) { }
     313             : 
     314             : template <size_t Size>
     315        4875 : inline CoderSource::CoderSource(const std::array<uint8_t, Size> &d) : _data(d.data(), Size), _offset(0) { }
     316             : 
     317        1525 : inline CoderSource::CoderSource() { }
     318             : 
     319       49563 : inline const uint8_t* CoderSource::data() const {
     320       49563 :         return _data.data() + _offset;
     321             : }
     322       57864 : inline size_t CoderSource::size() const {
     323       57864 :         return _data.size() - _offset;
     324             : }
     325        1900 : inline bool CoderSource::empty() const {
     326        1900 :         return _data.empty() || _offset == _data.size();
     327             : }
     328             : 
     329         105 : inline BytesViewTemplate<Endian::Network> CoderSource::view() const {
     330         105 :         return _data;
     331             : }
     332             : 
     333      124450 : inline uint8_t CoderSource::operator[](size_t s) const {
     334      124450 :         return _data[s + _offset];
     335             : }
     336             : 
     337      397375 : inline size_t CoderSource::read(uint8_t *buf, size_t nbytes) {
     338      397375 :         const auto remains = _data.size() - _offset;
     339      397375 :         if (nbytes > remains) {
     340          75 :                 nbytes = remains;
     341             :         }
     342      397375 :         memcpy(buf, _data.data() + _offset, nbytes);
     343      397375 :         _offset += nbytes;
     344      397375 :         return nbytes;
     345             : }
     346             : 
     347        1475 : inline size_t CoderSource::seek(int64_t offset, io::Seek s) {
     348        1475 :         switch (s) {
     349          75 :         case io::Seek::Current:
     350          75 :                 if (offset + _offset > _data.size()) {
     351          50 :                         _offset = _data.size();
     352          25 :                 } else if (offset + int64_t(_offset) < 0) {
     353           0 :                         _offset = 0;
     354             :                 } else {
     355          25 :                         _offset += offset;
     356             :                 }
     357          75 :                 break;
     358          75 :         case io::Seek::End:
     359          75 :                 if (offset > 0) {
     360          25 :                         _offset = _data.size();
     361          50 :                 } else if (size_t(-offset) > _data.size()) {
     362          25 :                         _offset = 0;
     363             :                 } else {
     364          25 :                         _offset = size_t(-offset);
     365             :                 }
     366          75 :                 break;
     367        1325 :         case io::Seek::Set:
     368        1325 :                 if (offset < 0) {
     369          25 :                         _offset = 0;
     370        1300 :                 } else if (size_t(offset) <= _data.size()) {
     371        1275 :                         _offset = size_t(offset);
     372             :                 } else {
     373          25 :                         _offset = _data.size();
     374             :                 }
     375        1325 :                 break;
     376             :         }
     377        1475 :         return _offset;
     378             : }
     379             : 
     380          25 : inline size_t CoderSource::tell() const {
     381          25 :         return _offset;
     382             : }
     383             : 
     384             : }
     385             : 
     386             : 
     387             : namespace STAPPLER_VERSIONIZED stappler::crypto {
     388             : 
     389             : template <typename ... Args>
     390             : inline Sha512::Buf Sha512::perform(Args && ... args) {
     391             :         Sha512 ctx;
     392             :         ctx._update(std::forward<Args>(args)...);
     393             :         return ctx.final();
     394             : }
     395             : 
     396             : template  <typename T, typename ... Args>
     397             : inline void Sha512::_update(T && t, Args && ... args) {
     398             :         update(std::forward<T>(t));
     399             :         _update(std::forward<Args>(args)...);
     400             : }
     401             : 
     402             : template  <typename T>
     403             : inline void Sha512::_update(T && t) {
     404             :         update(std::forward<T>(t));
     405             : }
     406             : 
     407             : template <typename ... Args>
     408             : inline Sha256::Buf Sha256::perform(Args && ... args) {
     409             :         Sha256 ctx;
     410             :         ctx._update(std::forward<Args>(args)...);
     411             :         return ctx.final();
     412             : }
     413             : 
     414             : template  <typename T, typename ... Args>
     415             : inline void Sha256::_update(T && t, Args && ... args) {
     416             :         update(std::forward<T>(t));
     417             :         _update(std::forward<Args>(args)...);
     418             : }
     419             : 
     420             : template  <typename T>
     421             : inline void Sha256::_update(T && t) {
     422             :         update(std::forward<T>(t));
     423             : }
     424             : 
     425             : template <typename ... Args>
     426             : inline Gost3411_512::Buf Gost3411_512::perform(Args && ... args) {
     427             :         Gost3411_512 c;
     428             :         c._update(std::forward<Args>(args)...);
     429             :         return c.final();
     430             : }
     431             : 
     432             : template  <typename T, typename ... Args>
     433             : inline void Gost3411_512::_update(T && t, Args && ... args) {
     434             :         update(std::forward<T>(t));
     435             :         _update(std::forward<Args>(args)...);
     436             : }
     437             : 
     438             : template  <typename T>
     439             : inline void Gost3411_512::_update(T && t) {
     440             :         update(std::forward<T>(t));
     441             : }
     442             : 
     443             : template <typename ... Args>
     444             : inline Gost3411_256::Buf Gost3411_256::perform(Args && ... args) {
     445             :         Gost3411_256 c;
     446             :         c._update(std::forward<Args>(args)...);
     447             :         return c.final();
     448             : }
     449             : 
     450             : template  <typename T, typename ... Args>
     451             : inline void Gost3411_256::_update(T && t, Args && ... args) {
     452             :         update(std::forward<T>(t));
     453             :         _update(std::forward<Args>(args)...);
     454             : }
     455             : 
     456             : template  <typename T>
     457             : inline void Gost3411_256::_update(T && t) {
     458             :         update(std::forward<T>(t));
     459             : }
     460             : 
     461             : }
     462             : 
     463             : 
     464             : namespace STAPPLER_VERSIONIZED stappler::io {
     465             : 
     466             : template <>
     467             : struct ProducerTraits<CoderSource> {
     468             :         using type = CoderSource;
     469        1275 :         static size_t ReadFn(void *ptr, uint8_t *buf, size_t nbytes) {
     470        1275 :                 return ((type *)ptr)->read(buf, nbytes);
     471             :         }
     472             : 
     473        1225 :         static size_t SeekFn(void *ptr, int64_t offset, Seek s) {
     474        1225 :                 return ((type *)ptr)->seek(offset, s);
     475             :         }
     476           0 :         static size_t TellFn(void *ptr) {
     477           0 :                 return ((type *)ptr)->tell();
     478             :         }
     479             : };
     480             : 
     481             : }
     482             : 
     483             : #endif /* STAPPLER_CORE_STRING_SPCRYPTO_H_ */

Generated by: LCOV version 1.14