LCOV - code coverage report
Current view: top level - src/crypto - base64.cc (source / functions) Hit Total Coverage
Test: mosh-1.3.2 Code Coverage Lines: 36 36 100.0 %
Date: 2022-02-06 20:19:53 Functions: 2 2 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :     Mosh: the mobile shell
       3             :     Copyright 2012 Keith Winstein
       4             : 
       5             :     This program is free software: you can redistribute it and/or modify
       6             :     it under the terms of the GNU General Public License as published by
       7             :     the Free Software Foundation, either version 3 of the License, or
       8             :     (at your option) any later version.
       9             : 
      10             :     This program is distributed in the hope that it will be useful,
      11             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13             :     GNU General Public License for more details.
      14             : 
      15             :     You should have received a copy of the GNU General Public License
      16             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
      17             : 
      18             :     In addition, as a special exception, the copyright holders give
      19             :     permission to link the code of portions of this program with the
      20             :     OpenSSL library under certain conditions as described in each
      21             :     individual source file, and distribute linked combinations including
      22             :     the two.
      23             : 
      24             :     You must obey the GNU General Public License in all respects for all
      25             :     of the code used other than OpenSSL. If you modify file(s) with this
      26             :     exception, you may extend this exception to your version of the
      27             :     file(s), but you are not obligated to do so. If you do not wish to do
      28             :     so, delete this exception statement from your version. If you delete
      29             :     this exception statement from all source files in the program, then
      30             :     also delete it here.
      31             : */
      32             : 
      33             : #include <string.h>
      34             : #include <stdlib.h>
      35             : 
      36             : #include "fatal_assert.h"
      37             : #include "base64.h"
      38             : 
      39             : static const char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
      40             : 
      41             : static const unsigned char reverse[] = {
      42             :   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
      43             :   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
      44             :   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f,
      45             :   0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
      46             :   0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
      47             :   0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff,
      48             :   0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
      49             :   0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
      50             :   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
      51             :   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
      52             :   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
      53             :   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
      54             :   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
      55             :   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
      56             :   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
      57             :   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
      58             : };
      59             : 
      60             : /* Reverse maps from an ASCII char to a base64 sixbit value.  Returns > 0x3f on failure. */
      61     5788730 : static unsigned char base64_char_to_sixbit(unsigned char c)
      62             : {
      63     5788730 :   return reverse[c];
      64             : }
      65             : 
      66      263130 : bool base64_decode( const char *b64, const size_t b64_len,
      67             :                     uint8_t *raw, size_t *raw_len )
      68             : {
      69      263130 :   fatal_assert( b64_len == 24 ); /* only useful for Mosh keys */
      70      263130 :   fatal_assert( *raw_len == 16 );
      71             : 
      72             :   uint32_t bytes = 0;
      73     6051846 :   for (int i = 0; i < 22; i++) {
      74     5788730 :     unsigned char sixbit = base64_char_to_sixbit(*(b64++));
      75     5788730 :     if (sixbit > 0x3f) {
      76             :       return false;
      77             :     }
      78     5788716 :     bytes <<= 6;
      79     5788716 :     bytes |= sixbit;
      80             :     /* write groups of 3 */
      81     5788716 :     if (i % 4 == 3) {
      82     1315618 :       raw[0] = bytes >> 16;
      83     1315618 :       raw[1] = bytes >> 8;
      84     1315618 :       raw[2] = bytes;
      85     1315618 :       raw += 3;
      86     1315618 :       bytes = 0;
      87             :     }
      88             :   }
      89             :   /* last byte of output */
      90      263116 :   *raw = bytes >> 4;
      91      263116 :   if (b64[0] != '=' || b64[1] != '=') {
      92          12 :     return false;
      93             :   }
      94             :   return true;
      95             : }
      96             : 
      97     1049988 : void base64_encode( const uint8_t *raw, const size_t raw_len,
      98             :                     char *b64, const size_t b64_len )
      99             : {
     100     1049988 :   fatal_assert( b64_len == 24 ); /* only useful for Mosh keys */
     101     1049988 :   fatal_assert( raw_len == 16 );
     102             : 
     103             :   /* first 15 bytes of input */
     104     6299928 :   for (int i = 0; i < 5; i++) {
     105     5249940 :     uint32_t bytes = (raw[0] << 16) | (raw[1] << 8) | raw[2];
     106     5249940 :     b64[0] = table[(bytes >> 18) & 0x3f];
     107     5249940 :     b64[1] = table[(bytes >> 12) & 0x3f];
     108     5249940 :     b64[2] = table[(bytes >> 6) & 0x3f];
     109     5249940 :     b64[3] = table[(bytes) & 0x3f];
     110     5249940 :     raw += 3;
     111     5249940 :     b64 += 4;
     112             :   }
     113             :   
     114             :   /* last byte of input, last 4 of output */
     115     1049988 :   uint8_t lastchar = *raw;
     116     1049988 :   b64[0] = table[(lastchar >> 2) & 0x3f];
     117     1049988 :   b64[1] = table[(lastchar << 4) & 0x3f];
     118     1049988 :   b64[2] = '=';
     119     1049988 :   b64[3] = '=';
     120     1049988 : }

Generated by: LCOV version 1.14