@@ -63,17 +63,6 @@ const (
63
63
minHashSize = 59
64
64
)
65
65
66
- // magicCipherData is an IV for the 64 Blowfish encryption calls in
67
- // bcrypt(). It's the string "OrpheanBeholderScryDoubt" in big-endian bytes.
68
- var magicCipherData = []byte {
69
- 0x4f , 0x72 , 0x70 , 0x68 ,
70
- 0x65 , 0x61 , 0x6e , 0x42 ,
71
- 0x65 , 0x68 , 0x6f , 0x6c ,
72
- 0x64 , 0x65 , 0x72 , 0x53 ,
73
- 0x63 , 0x72 , 0x79 , 0x44 ,
74
- 0x6f , 0x75 , 0x62 , 0x74 ,
75
- }
76
-
77
66
type hashed struct {
78
67
hash []byte
79
68
salt []byte
@@ -111,6 +100,13 @@ func CompareHashAndPassword(hashedPassword, password []byte) error {
111
100
return err
112
101
}
113
102
103
+ // This is simply put here instead of in newfromhash only to avoid failed test
104
+ // Altough failed test can be easily altered
105
+ p .salt , err = base64Decode (p .salt )
106
+ if err != nil {
107
+ return err
108
+ }
109
+
114
110
otherHash , err := bcrypt (password , p .cost , p .salt )
115
111
if err != nil {
116
112
return err
@@ -156,12 +152,14 @@ func newFromPassword(password []byte, cost int) (*hashed, error) {
156
152
return nil , err
157
153
}
158
154
159
- p .salt = base64Encode (unencodedSalt )
160
- hash , err := bcrypt (password , p .cost , p .salt )
155
+ hash , err := bcrypt (password , p .cost , unencodedSalt )
161
156
if err != nil {
162
157
return nil , err
163
158
}
159
+
160
+ p .salt = base64Encode (unencodedSalt )
164
161
p .hash = hash
162
+
165
163
return p , err
166
164
}
167
165
@@ -170,32 +168,38 @@ func newFromHash(hashedSecret []byte) (*hashed, error) {
170
168
return nil , ErrHashTooShort
171
169
}
172
170
p := new (hashed )
173
- n , err := p .decodeVersion (hashedSecret )
171
+ err := p .decodeVersion (& hashedSecret )
174
172
if err != nil {
175
173
return nil , err
176
174
}
177
- hashedSecret = hashedSecret [ n :]
178
- n , err = p .decodeCost (hashedSecret )
175
+
176
+ err = p .decodeCost (& hashedSecret )
179
177
if err != nil {
180
178
return nil , err
181
179
}
182
- hashedSecret = hashedSecret [n :]
183
180
184
181
// The "+2" is here because we'll have to append at most 2 '=' to the salt
185
182
// when base64 decoding it in expensiveBlowfishSetup().
186
183
p .salt = make ([]byte , encodedSaltSize , encodedSaltSize + 2 )
187
184
copy (p .salt , hashedSecret [:encodedSaltSize ])
188
185
189
- hashedSecret = hashedSecret [encodedSaltSize :]
190
- p .hash = make ([]byte , len (hashedSecret ))
191
- copy (p .hash , hashedSecret )
186
+ p .hash = make ([]byte , encodedHashSize )
187
+ copy (p .hash , hashedSecret [encodedSaltSize :])
192
188
193
189
return p , nil
194
190
}
195
191
196
192
func bcrypt (password []byte , cost int , salt []byte ) ([]byte , error ) {
197
- cipherData := make ([]byte , len (magicCipherData ))
198
- copy (cipherData , magicCipherData )
193
+ // magicCipherData is an IV for the 64 Blowfish encryption calls in
194
+ // bcrypt(). It's the string "OrpheanBeholderScryDoubt" in big-endian bytes.
195
+ var magicCipherData = []byte {
196
+ 0x4f , 0x72 , 0x70 , 0x68 ,
197
+ 0x65 , 0x61 , 0x6e , 0x42 ,
198
+ 0x65 , 0x68 , 0x6f , 0x6c ,
199
+ 0x64 , 0x65 , 0x72 , 0x53 ,
200
+ 0x63 , 0x72 , 0x79 , 0x44 ,
201
+ 0x6f , 0x75 , 0x62 , 0x74 ,
202
+ }
199
203
200
204
c , err := expensiveBlowfishSetup (password , uint32 (cost ), salt )
201
205
if err != nil {
@@ -204,28 +208,23 @@ func bcrypt(password []byte, cost int, salt []byte) ([]byte, error) {
204
208
205
209
for i := 0 ; i < 24 ; i += 8 {
206
210
for j := 0 ; j < 64 ; j ++ {
207
- c .Encrypt (cipherData [i :i + 8 ], cipherData [i :i + 8 ])
211
+ c .Encrypt (magicCipherData [i :i + 8 ], magicCipherData [i :i + 8 ])
208
212
}
209
213
}
210
214
211
215
// Bug compatibility with C bcrypt implementations. We only encode 23 of
212
216
// the 24 bytes encrypted.
213
- hsh := base64Encode (cipherData [:maxCryptedHashSize ])
217
+ hsh := base64Encode (magicCipherData [:maxCryptedHashSize ])
214
218
return hsh , nil
215
219
}
216
220
217
221
func expensiveBlowfishSetup (key []byte , cost uint32 , salt []byte ) (* blowfish.Cipher , error ) {
218
- csalt , err := base64Decode (salt )
219
- if err != nil {
220
- return nil , err
221
- }
222
-
223
222
// Bug compatibility with C bcrypt implementations. They use the trailing
224
223
// NULL in the key string during expansion.
225
224
// We copy the key to prevent changing the underlying array.
226
225
ckey := append (key [:len (key ):len (key )], 0 )
227
226
228
- c , err := blowfish .NewSaltedCipher (ckey , csalt )
227
+ c , err := blowfish .NewSaltedCipher (ckey , salt )
229
228
if err != nil {
230
229
return nil , err
231
230
}
@@ -234,7 +233,7 @@ func expensiveBlowfishSetup(key []byte, cost uint32, salt []byte) (*blowfish.Cip
234
233
rounds = 1 << cost
235
234
for i = 0 ; i < rounds ; i ++ {
236
235
blowfish .ExpandKey (ckey , c )
237
- blowfish .ExpandKey (csalt , c )
236
+ blowfish .ExpandKey (salt , c )
238
237
}
239
238
240
239
return c , nil
@@ -262,34 +261,39 @@ func (p *hashed) Hash() []byte {
262
261
return arr [:n ]
263
262
}
264
263
265
- func (p * hashed ) decodeVersion (sbytes []byte ) ( int , error ) {
266
- if sbytes [0 ] != '$' {
267
- return - 1 , InvalidHashPrefixError (sbytes [0 ])
264
+ func (p * hashed ) decodeVersion (sbytes * []byte ) error {
265
+ if ( * sbytes ) [0 ] != '$' {
266
+ return InvalidHashPrefixError (( * sbytes ) [0 ])
268
267
}
269
- if sbytes [1 ] > majorVersion {
270
- return - 1 , HashVersionTooNewError (sbytes [1 ])
268
+ if ( * sbytes ) [1 ] > majorVersion {
269
+ return HashVersionTooNewError (( * sbytes ) [1 ])
271
270
}
272
- p .major = sbytes [1 ]
271
+ p .major = ( * sbytes ) [1 ]
273
272
n := 3
274
- if sbytes [2 ] != '$' {
275
- p .minor = sbytes [2 ]
273
+ if ( * sbytes ) [2 ] != '$' {
274
+ p .minor = ( * sbytes ) [2 ]
276
275
n ++
277
276
}
278
- return n , nil
277
+
278
+ (* sbytes ) = (* sbytes )[n :]
279
+
280
+ return nil
279
281
}
280
282
281
283
// sbytes should begin where decodeVersion left off.
282
- func (p * hashed ) decodeCost (sbytes []byte ) (int , error ) {
283
- cost , err : = strconv .Atoi (string (sbytes [0 :2 ]))
284
+ func (p * hashed ) decodeCost (sbytes * []byte ) (err error ) {
285
+ p . cost , err = strconv .Atoi (string (( * sbytes ) [0 :2 ]))
284
286
if err != nil {
285
- return - 1 , err
287
+ return
286
288
}
287
- err = checkCost (cost )
289
+
290
+ err = checkCost (p .cost )
288
291
if err != nil {
289
- return - 1 , err
292
+ return
290
293
}
291
- p .cost = cost
292
- return 3 , nil
294
+
295
+ (* sbytes ) = (* sbytes )[3 :]
296
+ return
293
297
}
294
298
295
299
func (p * hashed ) String () string {
0 commit comments