LCOV - code coverage report
Current view: top level - libcli/auth - smbdes.c (source / functions) Hit Total Coverage
Test: coverage report for master 2b515b7d Lines: 86 97 88.7 %
Date: 2024-02-28 12:06:22 Functions: 9 9 100.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    a partial implementation of DES designed for use in the 
       5             :    SMB authentication protocol
       6             : 
       7             :    Copyright (C) Andrew Tridgell 1998
       8             :    
       9             :    This program is free software; you can redistribute it and/or modify
      10             :    it under the terms of the GNU General Public License as published by
      11             :    the Free Software Foundation; either version 3 of the License, or
      12             :    (at your option) any later version.
      13             :    
      14             :    This program is distributed in the hope that it will be useful,
      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :    GNU General Public License for more details.
      18             :    
      19             :    You should have received a copy of the GNU General Public License
      20             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      21             : */
      22             : 
      23             : #include "includes.h"
      24             : #include "libcli/auth/libcli_auth.h"
      25             : 
      26             : #include <gnutls/gnutls.h>
      27             : #include <gnutls/crypto.h>
      28             : 
      29      185326 : static void str_to_key(const uint8_t *str,uint8_t *key)
      30             : {
      31        3745 :         int i;
      32             : 
      33      185326 :         key[0] = str[0]>>1;
      34      185326 :         key[1] = ((str[0]&0x01)<<6) | (str[1]>>2);
      35      185326 :         key[2] = ((str[1]&0x03)<<5) | (str[2]>>3);
      36      185326 :         key[3] = ((str[2]&0x07)<<4) | (str[3]>>4);
      37      185326 :         key[4] = ((str[3]&0x0F)<<3) | (str[4]>>5);
      38      185326 :         key[5] = ((str[4]&0x1F)<<2) | (str[5]>>6);
      39      185326 :         key[6] = ((str[5]&0x3F)<<1) | (str[6]>>7);
      40      185326 :         key[7] = str[6]&0x7F;
      41     1667934 :         for (i=0;i<8;i++) {
      42     1482608 :                 key[i] = (key[i]<<1);
      43             :         }
      44      185326 : }
      45             : 
      46      185326 : int des_crypt56_gnutls(uint8_t out[8], const uint8_t in[8],
      47             :                        const uint8_t key_in[7],
      48             :                        enum samba_gnutls_direction encrypt)
      49             : {
      50             :         /*
      51             :          * A single block DES-CBC op, with an all-zero IV is the same as DES
      52             :          * because the IV is combined with the data using XOR.
      53             :          * This allows us to use GNUTLS_CIPHER_DES_CBC from GnuTLS and not
      54             :          * implement single-DES in Samba.
      55             :          *
      56             :          * In turn this is used to build DES-ECB, which is used
      57             :          * for example in the NTLM challenge/response calculation.
      58             :          */
      59        3745 :         static const uint8_t iv8[8];
      60      185326 :         gnutls_datum_t iv = { discard_const(iv8), 8 };
      61        3745 :         gnutls_datum_t key;
      62        3745 :         gnutls_cipher_hd_t ctx;
      63        3745 :         uint8_t key2[8];
      64        3745 :         uint8_t outb[8];
      65        3745 :         int ret;
      66             : 
      67      185326 :         memset(out, 0, 8);
      68             : 
      69      185326 :         str_to_key(key_in, key2);
      70             : 
      71      185326 :         key.data = key2;
      72      185326 :         key.size = 8;
      73             : 
      74      185326 :         ret = gnutls_global_init();
      75      185326 :         if (ret != 0) {
      76           0 :                 return ret;
      77             :         }
      78             : 
      79      185326 :         ret = gnutls_cipher_init(&ctx, GNUTLS_CIPHER_DES_CBC, &key, &iv);
      80      185326 :         if (ret != 0) {
      81           0 :                 return ret;
      82             :         }
      83             : 
      84      185326 :         memcpy(outb, in, 8);
      85      185326 :         if (encrypt == SAMBA_GNUTLS_ENCRYPT) {
      86      154119 :                 ret = gnutls_cipher_encrypt(ctx, outb, 8);
      87             :         } else {
      88       31207 :                 ret = gnutls_cipher_decrypt(ctx, outb, 8);
      89             :         }
      90             : 
      91      185326 :         if (ret == 0) {
      92      185326 :                 memcpy(out, outb, 8);
      93             :         }
      94             : 
      95      185326 :         gnutls_cipher_deinit(ctx);
      96             : 
      97      185326 :         return ret;
      98             : }
      99             : 
     100       10231 : int E_P16(const uint8_t *p14,uint8_t *p16)
     101             : {
     102       10231 :         const uint8_t sp8[8] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};
     103          15 :         int ret;
     104             : 
     105       10231 :         ret = des_crypt56_gnutls(p16, sp8, p14, SAMBA_GNUTLS_ENCRYPT);
     106       10231 :         if (ret != 0) {
     107           0 :                 return ret;
     108             :         }
     109             : 
     110       10231 :         return des_crypt56_gnutls(p16+8, sp8, p14+7, SAMBA_GNUTLS_ENCRYPT);
     111             : }
     112             : 
     113       11980 : int E_P24(const uint8_t *p21, const uint8_t *c8, uint8_t *p24)
     114             : {
     115          19 :         int ret;
     116             : 
     117       11980 :         ret = des_crypt56_gnutls(p24, c8, p21, SAMBA_GNUTLS_ENCRYPT);
     118       11980 :         if (ret != 0) {
     119           0 :                 return ret;
     120             :         }
     121             : 
     122       11980 :         ret = des_crypt56_gnutls(p24+8, c8, p21+7, SAMBA_GNUTLS_ENCRYPT);
     123       11980 :         if (ret != 0) {
     124           0 :                 return ret;
     125             :         }
     126             : 
     127       11980 :         return des_crypt56_gnutls(p24+16, c8, p21+14, SAMBA_GNUTLS_ENCRYPT);
     128             : }
     129             : 
     130        3361 : int E_old_pw_hash( uint8_t *p14, const uint8_t *in, uint8_t *out)
     131             : {
     132           1 :         int ret;
     133             : 
     134        3361 :         ret = des_crypt56_gnutls(out, in, p14, SAMBA_GNUTLS_ENCRYPT);
     135        3361 :         if (ret != 0) {
     136           0 :                 return ret;
     137             :         }
     138             : 
     139        3361 :         return des_crypt56_gnutls(out+8, in+8, p14+7, SAMBA_GNUTLS_ENCRYPT);
     140             : }
     141             : 
     142             : /* des encryption with a 128 bit key */
     143         460 : int des_crypt128(uint8_t out[8], const uint8_t in[8], const uint8_t key[16])
     144             : {
     145          49 :         uint8_t buf[8];
     146          49 :         int ret;
     147             : 
     148         460 :         ret = des_crypt56_gnutls(buf, in, key, SAMBA_GNUTLS_ENCRYPT);
     149         460 :         if (ret != 0) {
     150           0 :                 return ret;
     151             :         }
     152             : 
     153         460 :         return des_crypt56_gnutls(out, buf, key+9, SAMBA_GNUTLS_ENCRYPT);
     154             : }
     155             : 
     156             : /* des encryption with a 112 bit (14 byte) key */
     157       27772 : int des_crypt112(uint8_t out[8], const uint8_t in[8], const uint8_t key[14],
     158             :                  enum samba_gnutls_direction encrypt)
     159             : {
     160        1734 :         uint8_t buf[8];
     161        1734 :         int ret;
     162             : 
     163       27772 :         if (encrypt == SAMBA_GNUTLS_ENCRYPT) {
     164       27771 :                 ret = des_crypt56_gnutls(buf, in, key, SAMBA_GNUTLS_ENCRYPT);
     165       27771 :                 if (ret != 0) {
     166           0 :                         return ret;
     167             :                 }
     168             : 
     169       27771 :                 return des_crypt56_gnutls(out, buf, key+7, SAMBA_GNUTLS_ENCRYPT);
     170             :         }
     171             : 
     172           1 :         ret = des_crypt56_gnutls(buf, in, key+7, SAMBA_GNUTLS_DECRYPT);
     173           1 :         if (ret != 0) {
     174           0 :                 return ret;
     175             :         }
     176             : 
     177           1 :         return des_crypt56_gnutls(out, buf, key, SAMBA_GNUTLS_DECRYPT);
     178             : }
     179             : 
     180             : /* des encryption of a 16 byte lump of data with a 112 bit key */
     181         371 : int des_crypt112_16(uint8_t out[16], const uint8_t in[16], const uint8_t key[14],
     182             :                     enum samba_gnutls_direction encrypt)
     183             : {
     184          35 :         int ret;
     185             : 
     186         371 :         ret = des_crypt56_gnutls(out, in, key, encrypt);
     187         371 :         if (ret != 0) {
     188           0 :                 return ret;
     189             :         }
     190             : 
     191         371 :         return des_crypt56_gnutls(out + 8, in + 8, key+7, encrypt);
     192             : }
     193             : 
     194             : /* Decode a sam password hash into a password.  The password hash is the
     195             :    same method used to store passwords in the NT registry.  The DES key
     196             :    used is based on the RID of the user. */
     197       17621 : int sam_rid_crypt(unsigned int rid, const uint8_t *in, uint8_t *out,
     198             :                   enum samba_gnutls_direction encrypt)
     199             : {
     200           5 :         uint8_t s[14];
     201           5 :         int ret;
     202             : 
     203       17621 :         s[0] = s[4] = s[8] = s[12] = (uint8_t)(rid & 0xFF);
     204       17621 :         s[1] = s[5] = s[9] = s[13] = (uint8_t)((rid >> 8) & 0xFF);
     205       17621 :         s[2] = s[6] = s[10]        = (uint8_t)((rid >> 16) & 0xFF);
     206       17621 :         s[3] = s[7] = s[11]        = (uint8_t)((rid >> 24) & 0xFF);
     207             : 
     208       17621 :         ret = des_crypt56_gnutls(out, in, s, encrypt);
     209       17621 :         if (ret != 0) {
     210           0 :                 return ret;
     211             :         }
     212       17621 :         return des_crypt56_gnutls(out+8, in+8, s+7, encrypt);
     213             : }

Generated by: LCOV version 1.14