gitee.com/ks-custle/core-gm@v0.0.0-20230922171213-b83bdd97b62c/xcrypto/pkcs12/pbkdf.go (about) 1 // Copyright 2015 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package pkcs12 6 7 import ( 8 "bytes" 9 "crypto/sha1" 10 "math/big" 11 ) 12 13 var ( 14 one = big.NewInt(1) 15 ) 16 17 // sha1Sum returns the SHA-1 hash of in. 18 func sha1Sum(in []byte) []byte { 19 sum := sha1.Sum(in) 20 return sum[:] 21 } 22 23 // fillWithRepeats returns v*ceiling(len(pattern) / v) bytes consisting of 24 // repeats of pattern. 25 func fillWithRepeats(pattern []byte, v int) []byte { 26 if len(pattern) == 0 { 27 return nil 28 } 29 outputLen := v * ((len(pattern) + v - 1) / v) 30 return bytes.Repeat(pattern, (outputLen+len(pattern)-1)/len(pattern))[:outputLen] 31 } 32 33 func pbkdf(hash func([]byte) []byte, u, v int, salt, password []byte, r int, ID byte, size int) (key []byte) { 34 // implementation of https://tools.ietf.org/html/rfc7292#appendix-B.2 , RFC text verbatim in comments 35 36 // Let H be a hash function built around a compression function f: 37 38 // Z_2^u x Z_2^v -> Z_2^u 39 40 // (that is, H has a chaining variable and output of length u bits, and 41 // the message input to the compression function of H is v bits). The 42 // values for u and v are as follows: 43 44 // HASH FUNCTION VALUE u VALUE v 45 // MD2, MD5 128 512 46 // SHA-1 160 512 47 // SHA-224 224 512 48 // SHA-256 256 512 49 // SHA-384 384 1024 50 // SHA-512 512 1024 51 // SHA-512/224 224 1024 52 // SHA-512/256 256 1024 53 54 // Furthermore, let r be the iteration count. 55 56 // We assume here that u and v are both multiples of 8, as are the 57 // lengths of the password and salt strings (which we denote by p and s, 58 // respectively) and the number n of pseudorandom bits required. In 59 // addition, u and v are of course non-zero. 60 61 // For information on security considerations for MD5 [19], see [25] and 62 // [1], and on those for MD2, see [18]. 63 64 // The following procedure can be used to produce pseudorandom bits for 65 // a particular "purpose" that is identified by a byte called "ID". 66 // This standard specifies 3 different values for the ID byte: 67 68 // 1. If ID=1, then the pseudorandom bits being produced are to be used 69 // as key material for performing encryption or decryption. 70 71 // 2. If ID=2, then the pseudorandom bits being produced are to be used 72 // as an IV (Initial Value) for encryption or decryption. 73 74 // 3. If ID=3, then the pseudorandom bits being produced are to be used 75 // as an integrity key for MACing. 76 77 // 1. Construct a string, D (the "diversifier"), by concatenating v/8 78 // copies of ID. 79 var D []byte 80 for i := 0; i < v; i++ { 81 D = append(D, ID) 82 } 83 84 // 2. Concatenate copies of the salt together to create a string S of 85 // length v(ceiling(s/v)) bits (the final copy of the salt may be 86 // truncated to create S). Note that if the salt is the empty 87 // string, then so is S. 88 89 S := fillWithRepeats(salt, v) 90 91 // 3. Concatenate copies of the password together to create a string P 92 // of length v(ceiling(p/v)) bits (the final copy of the password 93 // may be truncated to create P). Note that if the password is the 94 // empty string, then so is P. 95 96 P := fillWithRepeats(password, v) 97 98 // 4. Set I=S||P to be the concatenation of S and P. 99 I := append(S, P...) 100 101 // 5. Set c=ceiling(n/u). 102 c := (size + u - 1) / u 103 104 // 6. For i=1, 2, ..., c, do the following: 105 A := make([]byte, c*20) 106 var IjBuf []byte 107 for i := 0; i < c; i++ { 108 // A. Set A2=H^r(D||I). (i.e., the r-th hash of D||1, 109 // H(H(H(... H(D||I)))) 110 Ai := hash(append(D, I...)) 111 for j := 1; j < r; j++ { 112 Ai = hash(Ai) 113 } 114 copy(A[i*20:], Ai[:]) 115 116 if i < c-1 { // skip on last iteration 117 // B. Concatenate copies of Ai to create a string B of length v 118 // bits (the final copy of Ai may be truncated to create B). 119 var B []byte 120 for len(B) < v { 121 B = append(B, Ai[:]...) 122 } 123 B = B[:v] 124 125 // C. Treating I as a concatenation I_0, I_1, ..., I_(k-1) of v-bit 126 // blocks, where k=ceiling(s/v)+ceiling(p/v), modify I by 127 // setting I_j=(I_j+B+1) mod 2^v for each j. 128 { 129 Bbi := new(big.Int).SetBytes(B) 130 Ij := new(big.Int) 131 132 for j := 0; j < len(I)/v; j++ { 133 Ij.SetBytes(I[j*v : (j+1)*v]) 134 Ij.Add(Ij, Bbi) 135 Ij.Add(Ij, one) 136 Ijb := Ij.Bytes() 137 // We expect Ijb to be exactly v bytes, 138 // if it is longer or shorter we must 139 // adjust it accordingly. 140 if len(Ijb) > v { 141 Ijb = Ijb[len(Ijb)-v:] 142 } 143 if len(Ijb) < v { 144 if IjBuf == nil { 145 IjBuf = make([]byte, v) 146 } 147 bytesShort := v - len(Ijb) 148 for i := 0; i < bytesShort; i++ { 149 IjBuf[i] = 0 150 } 151 copy(IjBuf[bytesShort:], Ijb) 152 Ijb = IjBuf 153 } 154 copy(I[j*v:(j+1)*v], Ijb) 155 } 156 } 157 } 158 } 159 // 7. Concatenate A_1, A_2, ..., A_c together to form a pseudorandom 160 // bit string, A. 161 162 // 8. Use the first n bits of A as the output of this entire process. 163 return A[:size] 164 165 // If the above process is being used to generate a DES key, the process 166 // should be used to create 64 random bits, and the key's parity bits 167 // should be set after the 64 bits have been produced. Similar concerns 168 // hold for 2-key and 3-key triple-DES keys, for CDMF keys, and for any 169 // similar keys with parity bits "built into them". 170 }