{"record":{"id":"528bcb476c2a9a90","repo":"XTLS/Xray-core","slug":"generate-shared-secret-w","errorCode":null,"errorMessage":"generate shared secret: %w","messagePattern":"generate shared secret: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"transport/internet/finalmask/xmc/client.go","lineNumber":157,"sourceCode":"\t}\n\n\tif !bytes.Equal(publicKey, c.rsaPublicKey) {\n\t\treturn fmt.Errorf(\"server public key mismatch\")\n\t}\n\n\tk, err := x509.ParsePKIXPublicKey(publicKey)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"parse server public key: %w\", err)\n\t}\n\n\trsaPublicKey, ok := k.(*rsa.PublicKey)\n\tif !ok {\n\t\treturn fmt.Errorf(\"parse server public key: not rsa\")\n\t}\n\n\tsharedSecret := make([]byte, 16)\n\tif _, err = rand.Read(sharedSecret); err != nil {\n\t\treturn fmt.Errorf(\"generate shared secret: %w\", err)\n\t}\n\n\tencryptedSharedSecret, err := rsa.EncryptPKCS1v15(rand.Reader, rsaPublicKey, sharedSecret)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"encrypt shared secret: %w\", err)\n\t}\n\n\tverifyToken = append(verifyToken, []byte(c.password)...) // append pre-shared password\n\n\tencryptedVerifyToken, err := rsa.EncryptPKCS1v15(rand.Reader, rsaPublicKey, verifyToken)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"encrypt verify token: %w\", err)\n\t}\n\n\t// Send Encryption Response\n\terr = writePacket(\n\t\tc.writer,\n\t\t0x01,","sourceCodeStart":139,"sourceCodeEnd":175,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/transport/internet/finalmask/xmc/client.go#L139-L175","documentation":"crypto/rand.Read failed while filling the 16-byte AES shared secret used for the symmetric stream after the RSA exchange. This is an entropy-source failure from the OS CSPRNG, not a protocol error. On Linux crypto/rand essentially never fails unless getrandom(2) is unavailable (very old kernels, broken seccomp filters, or exhausted fd-restricted entropy setups in exotic sandboxes).","triggerScenarios":"First Read/Write on a WrapConnClient connection triggers handshake(), which calls rand.Read(sharedSecret); the call returns an error, e.g. under a container/seccomp profile that blocks getrandom, or on a kernel older than 3.17 without /dev/urandom available.","commonSituations":"Overly restrictive Docker/gVisor/seccomp sandboxes; chroot environments without /dev/urandom mounted; some minimal VMs or WASM targets. Extremely rare on normal hosts.","solutions":["Verify /dev/urandom exists and is readable inside the environment (ls -l /dev/urandom && head -c 16 /dev/urandom >/dev/null)","Relax the seccomp/container profile to allow the getrandom syscall (Docker default profiles already do)","Move the workload to a standard kernel >= 3.17","If running under a WASM/embedded target, provide a platform CSPRNG or run the tunnel on the host side"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if _, err := rand.Read(make([]byte, 16)); err != nil {\n    return fmt.Errorf(\"environment CSPRNG unavailable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"n, err := conn.Read(buf)\nif err != nil && strings.Contains(err.Error(), \"generate shared secret\") {\n    // entropy source failure: fix the runtime environment, do not retry in-process\n    log.Fatal(\"CSPRNG unavailable; check /dev/urandom and seccomp profile\")\n}","preventionTips":["Smoke-test crypto/rand.Read at app startup in sandboxed deployments","Allow the getrandom syscall in container/seccomp profiles","Ensure /dev/urandom is mounted in chroot/minimal containers"],"tags":["crypto","entropy","sandbox","environment","go"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}