Subversion Repositories oidplus

Rev

Rev 827 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 827 Rev 874
Line 1... Line 1...
1
<?php
1
<?php
2
declare(strict_types=1);
2
declare(strict_types=1);
3
namespace ParagonIE\ConstantTime;
3
namespace ParagonIE\ConstantTime;
4
 
4
 
-
 
5
use RangeException;
-
 
6
use TypeError;
-
 
7
 
5
/**
8
/**
6
 *  Copyright (c) 2016 - 2018 Paragon Initiative Enterprises.
9
 *  Copyright (c) 2016 - 2022 Paragon Initiative Enterprises.
7
 *  Copyright (c) 2014 Steve "Sc00bz" Thomas (steve at tobtu dot com)
10
 *  Copyright (c) 2014 Steve "Sc00bz" Thomas (steve at tobtu dot com)
8
 *
11
 *
9
 *  Permission is hereby granted, free of charge, to any person obtaining a copy
12
 *  Permission is hereby granted, free of charge, to any person obtaining a copy
10
 *  of this software and associated documentation files (the "Software"), to deal
13
 *  of this software and associated documentation files (the "Software"), to deal
11
 *  in the Software without restriction, including without limitation the rights
14
 *  in the Software without restriction, including without limitation the rights
Line 35... Line 38...
35
     * Convert a binary string into a hexadecimal string without cache-timing
38
     * Convert a binary string into a hexadecimal string without cache-timing
36
     * leaks
39
     * leaks
37
     *
40
     *
38
     * @param string $binString (raw binary)
41
     * @param string $binString (raw binary)
39
     * @return string
42
     * @return string
40
     * @throws \TypeError
43
     * @throws TypeError
41
     */
44
     */
42
    public static function encode(string $binString): string
45
    public static function encode(string $binString): string
43
    {
46
    {
44
        $hex = '';
47
        $hex = '';
45
        $len = Binary::safeStrlen($binString);
48
        $len = Binary::safeStrlen($binString);
46
        for ($i = 0; $i < $len; ++$i) {
49
        for ($i = 0; $i < $len; ++$i) {
47
            /** @var array<int, int> $chunk */
50
            /** @var array<int, int> $chunk */
48
            $chunk = \unpack('C', Binary::safeSubstr($binString, $i, 1));
51
            $chunk = \unpack('C', $binString[$i]);
49
            $c = $chunk[1] & 0xf;
52
            $c = $chunk[1] & 0xf;
50
            $b = $chunk[1] >> 4;
53
            $b = $chunk[1] >> 4;
51
 
54
 
52
            $hex .= pack(
55
            $hex .= \pack(
53
                'CC',
56
                'CC',
54
                (87 + $b + ((($b - 10) >> 8) & ~38)),
57
                (87 + $b + ((($b - 10) >> 8) & ~38)),
55
                (87 + $c + ((($c - 10) >> 8) & ~38))
58
                (87 + $c + ((($c - 10) >> 8) & ~38))
56
            );
59
            );
57
        }
60
        }
Line 62... Line 65...
62
     * Convert a binary string into a hexadecimal string without cache-timing
65
     * Convert a binary string into a hexadecimal string without cache-timing
63
     * leaks, returning uppercase letters (as per RFC 4648)
66
     * leaks, returning uppercase letters (as per RFC 4648)
64
     *
67
     *
65
     * @param string $binString (raw binary)
68
     * @param string $binString (raw binary)
66
     * @return string
69
     * @return string
67
     * @throws \TypeError
70
     * @throws TypeError
68
     */
71
     */
69
    public static function encodeUpper(string $binString): string
72
    public static function encodeUpper(string $binString): string
70
    {
73
    {
71
        $hex = '';
74
        $hex = '';
72
        $len = Binary::safeStrlen($binString);
75
        $len = Binary::safeStrlen($binString);
73
 
76
 
74
        for ($i = 0; $i < $len; ++$i) {
77
        for ($i = 0; $i < $len; ++$i) {
75
            /** @var array<int, int> $chunk */
78
            /** @var array<int, int> $chunk */
76
            $chunk = \unpack('C', Binary::safeSubstr($binString, $i, 2));
79
            $chunk = \unpack('C', $binString[$i]);
77
            $c = $chunk[1] & 0xf;
80
            $c = $chunk[1] & 0xf;
78
            $b = $chunk[1] >> 4;
81
            $b = $chunk[1] >> 4;
79
 
82
 
80
            $hex .= pack(
83
            $hex .= \pack(
81
                'CC',
84
                'CC',
82
                (55 + $b + ((($b - 10) >> 8) & ~6)),
85
                (55 + $b + ((($b - 10) >> 8) & ~6)),
83
                (55 + $c + ((($c - 10) >> 8) & ~6))
86
                (55 + $c + ((($c - 10) >> 8) & ~6))
84
            );
87
            );
85
        }
88
        }
Line 91... Line 94...
91
     * leaks
94
     * leaks
92
     *
95
     *
93
     * @param string $encodedString
96
     * @param string $encodedString
94
     * @param bool $strictPadding
97
     * @param bool $strictPadding
95
     * @return string (raw binary)
98
     * @return string (raw binary)
96
     * @throws \RangeException
99
     * @throws RangeException
97
     */
100
     */
-
 
101
    public static function decode(
-
 
102
        string $encodedString,
98
    public static function decode(string $encodedString, bool $strictPadding = false): string
103
        bool $strictPadding = false
99
    {
104
    ): string {
100
        $hex_pos = 0;
105
        $hex_pos = 0;
101
        $bin = '';
106
        $bin = '';
102
        $c_acc = 0;
107
        $c_acc = 0;
103
        $hex_len = Binary::safeStrlen($encodedString);
108
        $hex_len = Binary::safeStrlen($encodedString);
104
        $state = 0;
109
        $state = 0;
105
        if (($hex_len & 1) !== 0) {
110
        if (($hex_len & 1) !== 0) {
106
            if ($strictPadding) {
111
            if ($strictPadding) {
107
                throw new \RangeException(
112
                throw new RangeException(
108
                    'Expected an even number of hexadecimal characters'
113
                    'Expected an even number of hexadecimal characters'
109
                );
114
                );
110
            } else {
115
            } else {
111
                $encodedString = '0' . $encodedString;
116
                $encodedString = '0' . $encodedString;
112
                ++$hex_len;
117
                ++$hex_len;
Line 122... Line 127...
122
            $c_num0 = ($c_num - 10) >> 8;
127
            $c_num0 = ($c_num - 10) >> 8;
123
            $c_alpha = ($c & ~32) - 55;
128
            $c_alpha = ($c & ~32) - 55;
124
            $c_alpha0 = (($c_alpha - 10) ^ ($c_alpha - 16)) >> 8;
129
            $c_alpha0 = (($c_alpha - 10) ^ ($c_alpha - 16)) >> 8;
125
 
130
 
126
            if (($c_num0 | $c_alpha0) === 0) {
131
            if (($c_num0 | $c_alpha0) === 0) {
127
                throw new \RangeException(
132
                throw new RangeException(
128
                    'Expected hexadecimal character'
133
                    'Expected hexadecimal character'
129
                );
134
                );
130
            }
135
            }
131
            $c_val = ($c_num0 & $c_num) | ($c_alpha & $c_alpha0);
136
            $c_val = ($c_num0 & $c_num) | ($c_alpha & $c_alpha0);
132
            if ($state === 0) {
137
            if ($state === 0) {