Coverage Report

Created: 2025-11-16 06:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/samba/third_party/heimdal/lib/krb5/n-fold.c
Line
Count
Source
1
/*
2
 * Copyright (c) 1999 Kungliga Tekniska Högskolan
3
 * (Royal Institute of Technology, Stockholm, Sweden).
4
 * All rights reserved.
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
8
 * are met:
9
 *
10
 * 1. Redistributions of source code must retain the above copyright
11
 *    notice, this list of conditions and the following disclaimer.
12
 *
13
 * 2. Redistributions in binary form must reproduce the above copyright
14
 *    notice, this list of conditions and the following disclaimer in the
15
 *    documentation and/or other materials provided with the distribution.
16
 *
17
 * 3. Neither the name of KTH nor the names of its contributors may be
18
 *    used to endorse or promote products derived from this software without
19
 *    specific prior written permission.
20
 *
21
 * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY
22
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE
25
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
32
33
#include "krb5_locl.h"
34
35
static void
36
rr13(uint8_t *dst1, uint8_t *dst2, uint8_t *src, size_t len)
37
0
{
38
0
    int bytes = (len + 7) / 8;
39
0
    int i;
40
0
    const int bits = 13 % len;
41
42
0
    for (i = 0; i < bytes; i++) {
43
0
  int bb;
44
0
  int b1, s1, b2, s2;
45
  /* calculate first bit position of this byte */
46
0
  bb = 8 * i - bits;
47
0
  while(bb < 0)
48
0
      bb += len;
49
  /* byte offset and shift count */
50
0
  b1 = bb / 8;
51
0
  s1 = bb % 8;
52
53
0
  if (bb + 8 > bytes * 8)
54
      /* watch for wraparound */
55
0
      s2 = (len + 8 - s1) % 8;
56
0
  else
57
0
      s2 = 8 - s1;
58
0
  b2 = (b1 + 1) % bytes;
59
0
  dst1[i] = (src[b1] << s1) | (src[b2] >> s2);
60
0
  dst2[i] = dst1[i];
61
0
    }
62
63
0
    return;
64
0
}
65
66
/*
67
 * Add `b' to `a', both being one's complement numbers.
68
 * This function assumes that inputs *a, *b are aligned
69
 * to 4 bytes.
70
 */
71
static void
72
add1(uint8_t *a, uint8_t *b, size_t len)
73
0
{
74
0
    int i;
75
0
    int carry = 0;
76
0
    uint32_t x;
77
0
    uint32_t left, right;
78
79
0
    for (i = len - 1; (i+1) % 4; i--) {
80
0
  x = a[i] + b[i] + carry;
81
0
  carry = x > 0xff;
82
0
  a[i] = x & 0xff;
83
0
    }
84
85
0
    for (i = len / 4 - 1; i >= 0; i--) {
86
0
  left = ntohl(((uint32_t *)a)[i]);
87
0
  right = ntohl(((uint32_t *)b)[i]);
88
0
  x = left + right + carry;
89
0
  carry = x < left || x < right;
90
0
  ((uint32_t *)a)[i]  = x;
91
0
    }
92
93
0
    for (i = len - 1; (i+1) % 4; i--) {
94
0
  x = a[i] + carry;
95
0
  carry = x > 0xff;
96
0
  a[i] = x & 0xff;
97
0
    }
98
99
0
    for (i = len / 4 - 1; carry && i >= 0; i--) {
100
0
        left = ((uint32_t *)a)[i];
101
0
        x = left + carry;
102
0
        carry = x < left;
103
0
        ((uint32_t *)a)[i] = x;
104
0
    }
105
106
0
    for (i = len / 4 - 1; i >=0; i--)
107
0
        ((uint32_t *)a)[i] = htonl(((uint32_t *)a)[i]);
108
0
}
109
110
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
111
_krb5_n_fold(const void *str, size_t len, void *key, size_t size)
112
0
{
113
    /* if len < size we need at most N * len bytes, ie < 2 * size;
114
       if len > size we need at most 2 * len */
115
0
    size_t maxlen = 2 * max(size, len);
116
0
    size_t l = 0;
117
0
    uint8_t *tmp;
118
0
    uint8_t *tmpbuf;
119
0
    uint8_t *buf1;
120
0
    uint8_t *buf2;
121
122
0
    tmp = malloc(maxlen + 2 * len);
123
0
    if (tmp == NULL)
124
0
        return ENOMEM;
125
126
0
    buf1 = tmp + maxlen;
127
0
    buf2 = tmp + maxlen + len;
128
129
0
    memset(key, 0, size);
130
0
    memcpy(buf1, str, len);
131
0
    memcpy(tmp, buf1, len);
132
0
    do {
133
0
  l += len;
134
0
  while(l >= size) {
135
0
      add1(key, tmp, size);
136
0
      l -= size;
137
0
      if(l == 0)
138
0
    break;
139
0
      memmove(tmp, tmp + size, l);
140
0
  }
141
0
  rr13(tmp + l, buf2, buf1, len * 8);
142
0
  tmpbuf = buf1;
143
0
  buf1 = buf2;
144
0
  buf2 = tmpbuf;
145
0
    } while(l != 0);
146
147
0
    memset(tmp, 0, maxlen + 2 * len);
148
0
    free(tmp);
149
0
    return 0;
150
0
}