add: more rand.Read() checks

This commit is contained in:
Aleksandr Menenkov 2025-08-05 13:50:16 +03:00
parent c4b344958a
commit db68c07467
No known key found for this signature in database
3 changed files with 44 additions and 9 deletions

2
.gitignore vendored
View file

@ -20,5 +20,5 @@
# Go workspace file
go.work
go.work.sum
.idea/
TODO

35
rec.md Normal file
View file

@ -0,0 +1,35 @@
### Summary of Findings
1. **PCC-001**
- **Type:** Design decision
- **Description:** Data encrypted with Picocrypt is stored in a custom file format, including a header which is unauthenticated. As a result, any changes made by an attacker would go undetected.
- **Threat level:** Low
2. **PCC-004**
- **Type:** Cryptographic implementation
- **Description:** Picocrypt offers both encryption and authentication. When a user wants to decrypt a volume, it starts with decrypting and only verifies the signature afterwards. As a result a user may unknowingly use their private key on attacker-controlled material.
- **Threat level:** Low
3. **PCC-006**
- **Type:** Design decision
- **Description:** Picocrypt uses a memory-hard key derivation function to limit brute force attacks on the password. The output is then hashed using SHA3-512 and stored in the header, to verify the key before attempting to decrypt. As a result there are two algorithms that can be attacked individually which would both lead to the key.
- **Threat level:** N/A
### Summary of Recommendations
1. **PCC-001**
- **Type:** Design decision
- **Recommendation:**
- Authenticate data before processing. Since part of the header is required for key derivation, this is not possible. Adding authentication to the header would allow users to be informed if the header was tampered with (after key derivation, but before decryption).
2. **PCC-004**
- **Type:** Cryptographic implementation
- **Recommendation:**
- Authenticate the ciphertext before decrypting it.
3. **PCC-006**
- **Type:** Design decision
- **Recommendation:**
- Do not store the hash of the key in the header.
- Verify the signature before attempting to decrypt the volume.
- Consider replacing the hash with a MAC of the header.

View file

@ -1637,17 +1637,17 @@ func work() {
_, errs[3] = fout.Write(rsEncode(rs5, flags))
// Fill values with Go's CSPRNG
if _, err := rand.Read(salt); err != nil {
panic(err)
if n, err := rand.Read(salt); err != nil || n != 16 {
panic(errors.New("failed to read 16 bytes from crypto/rand"))
}
if _, err := rand.Read(hkdfSalt); err != nil {
panic(err)
if n, err := rand.Read(hkdfSalt); err != nil || n != 32 {
panic(errors.New("failed to read 32 bytes from crypto/rand"))
}
if _, err := rand.Read(serpentIV); err != nil {
panic(err)
if n, err := rand.Read(serpentIV); err != nil || n != 16 {
panic(errors.New("failed to read 16 bytes from crypto/rand"))
}
if _, err := rand.Read(nonce); err != nil {
panic(err)
if n, err := rand.Read(nonce); err != nil || n != 24 {
panic(errors.New("failed to read 24 bytes from crypto/rand"))
}
if bytes.Equal(salt, make([]byte, 16)) {
panic(errors.New("fatal crypto/rand error"))