
Research
/Security News
Laravel Lang Compromised with RCE Backdoor Across 700+ Versions
Laravel Lang packages were compromised with an RCE backdoor across hundreds of versions, exposing cloud, CI/CD, and developer secrets.
@pretendonetwork/boss-crypto
Advanced tools
TypeScript crypto functions for creating and working with WiiU and 3DS BOSS files
npm i @pretendonetwork/boss-crypto
BOSS uses 2 keys:
We cannot provide these keys directly as they are owned by Nintendo. You must dump them yourself from your console in order to use this library
To dump keys needed see this key dumping tool
Only one key is used to decrypt the contents, the AES encryption key. This is in keyslot 0x38 (Normalkey). See https://citra-emu.org/wiki/aes-keys/ and https://www.3dbrew.org/wiki/AES_Registers#Keyslots for more information. The SHA256 hashes are RSA signed, however we lack both the private and public key. So we cannot sign our own hashes legitimately and we cannot verify legitimate hashes. Luckily Luma patches these signature checks anyway
import fs from 'node:fs';
import { encryptWiiU } from '@pretendonetwork/boss-crypto';
const { BOSS_AES_KEY, BOSS_HMAC_KEY } = process.env;
const content = Buffer.from('Hello World');
const encrypted = encryptWiiU(content, BOSS_WIIU_AES_KEY, BOSS_WIIU_HMAC_KEY);
fs.writeFileSync(__dirname + '/Festival.boss', encrypted);
import fs from 'node:fs';
import { decryptWiiU } from '@pretendonetwork/boss-crypto';
const { BOSS_AES_KEY, BOSS_HMAC_KEY } = process.env;
const encryptedFilePath = __dirname + '/Festival.boss';
const { content } = decryptWiiU(encryptedFilePath, BOSS_AES_KEY, BOSS_HMAC_KEY);
fs.writeFileSync(__dirname + '/Festival.byml', content);
import fs from 'node:fs';
import { encrypt3DS } from '@pretendonetwork/boss-crypto';
const { BOSS_AES_KEY } = process.env;
const content = Buffer.from('Hello World');
const encrypted = encrypt3DS(BOSS_3DS_AES_KEY, 1692231927n, {
program_id: 0x0004001000022900, // can also be named "title_id"
content_datatype: 65537,
ns_data_id: 36,
version: 1,
content,
});
fs.writeFileSync(__dirname + '/hello-world.boss', encrypted);
import fs from 'node:fs';
import { decrypt3DS } from '@pretendonetwork/boss-crypto';
const { BOSS_AES_KEY } = process.env;
const encryptedFilePath = __dirname + '/EU_BGM1';
const { payload_contents } = decrypt3DS(encryptedFilePath, BOSS_AES_KEY);
fs.writeFileSync(__dirname + '/EU_BGM1.dec', payload_contents[0].content);
Returned when decrypting WiiU BOSS content. Contains some crypto information from the headers
THIS TYPE IS NOT PART OF THE REAL BOSS SPEC. IT IS MADE FOR THIS LIBRARY ONLY
type WUPBOSSInfo = {
hash_type: number;
iv: Buffer;
hmac: Buffer;
content: Buffer;
}
Holds flags representing additional information of a 3DS BOSS container
CTR_BOSS_FLAGS.MARK_ARRIVED_PRIVILEGED: If set, the titles which are targeted in the payload contents will only be notified of the arrival of new data if they are privileged titles. For example, this is used by regular titles downloading notification tasks which aren't targeted to the title itself, but to the notifications sysmoduleHolds the contents of one of the payloads of a 3DS BOSS container
type CTRPayloadContent = {
payload_content_header_hash: Buffer;
payload_content_header_hash_signature: Buffer;
program_id: bigint;
content_datatype: number;
ns_data_id: number;
version: number;
content: Buffer;
}
Returned when decrypting 3DS BOSS content. Contains all relevant data from the real BOSS container. See https://www.3dbrew.org/wiki/SpotPass#Content_Container for more details
type CTRBOSSContainer = {
hash_type: number;
serial_number: bigint;
iv: Buffer;
flags: CTRBOSSFlag;
content_header_hash: Buffer;
content_header_hash_signature: Buffer;
payload_contents: CTRPayloadContent[];
}
Passed in when encrypting 3DS contents. program_id and title_id are aliases, one must be set. serial_number and flags are only needed when calling encrypt. content is only needed when calling encrypt3DS
type CTRCryptoOptions = {
program_id?: string | number | bigint;
title_id?: string | number | bigint;
serial_number?: bigint;
flags?: CTRBOSSFlag;
content_datatype: number;
ns_data_id: number;
version: number;
content?: string | Buffer;
}
function decrypt(pathOrBuffer: string | Buffer, aesKey: string, hmacKey?: string): WUPBOSSInfo | CTRBOSSContainer
Takes in encrypted BOSS data and decrypts it. This function will check the BOSS header to see what version (WiiU or 3DS) the file is for and automatically call the corresponding decryption function
pathOrBuffer: Either a string path to the file or a buffer containing the raw dataaesKey: AES encryption keyhmacKey: HMAC key (WiiU only)WUPBOSSInfo | CTRBOSSContainer
function encrypt(pathOrBuffer: string | Buffer, version: number, aesKey: string, hmacKeyOrOptions: string | CTRCryptoOptions): Buffer
Takes in content and encrypts it. Will check version to know what version (WiiU or 3DS) the file is for and automatically call the corresponding encryption function
pathOrBuffer: Either a string path to the file or a buffer containing the raw dataversion: BOSS version number (0x10001 = 3DS, 0x20001 = WiiU)aesKey: BOSS AES encryption keyhmacKeyOrOptions: BOSS HMAC key (WiiU) or CTRCryptoOptions (3DS)Encrypted BOSS data buffer
function decryptWiiU(pathOrBuffer: string | Buffer, aesKey: string, hmacKey: string): WUPBOSSInfo
Takes in encrypted BOSS used for the WiiU data and decrypts it. This function is usually not needed and is called internally by decrypt
pathOrBuffer: Either a string path to the file or a buffer containing the raw dataaesKey: BOSS AES encryption keyhmacKey: BOSS HMAC keyWUPBOSSInfo
function encryptWiiU(pathOrBuffer: string | Buffer, aesKey: string, hmacKey: string): Buffer
Takes in content and encrypts it for the WiiU
pathOrBuffer: Either a string path to the file or a buffer containing the raw dataaesKey: BOSS AES encryption keyhmacKey: BOSS HMAC keyWiiU encrypted BOSS data
function decrypt3DS(pathOrBuffer: string | Buffer, aesKey: string | Buffer): CTRBOSSContainer
Takes in encrypted BOSS used for the 3DS data and decrypts it. This function is usually not needed and is called internally by decrypt
pathOrBuffer: Either a string path to the file or a buffer containing the raw dataaesKey: BOSS AES encryption keyCTRBOSSContainer
function encrypt3DS(aesKey: string | Buffer, serialNumber: bigint, options: CTRCryptoOptions[], flags?: CTRBOSSFlag): Buffer
Takes in multiple contents and encrypts them for the 3DS using the provided options and serial number
aesKey: BOSS AES encryption keyserialNumber: Serial number used in the BOSS container. This is a unique identifier of the container, similar to the data ID on the Wii U (not to be confused with the NS Data ID, which is assigned per payload content)options: Array of CTRCryptoOptionsflags: Container flags CTRBOSSFlag3DS encrypted BOSS data
FAQs
TypeScript crypto functions for creating and working with WiiU and 3DS BOSS files
We found that @pretendonetwork/boss-crypto demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
/Security News
Laravel Lang packages were compromised with an RCE backdoor across hundreds of versions, exposing cloud, CI/CD, and developer secrets.

Security News
Socket found a malicious postinstall hook across 700+ GitHub repos, including PHP packages on Packagist and Node.js project repositories.

Security News
Vibe coding at scale is reshaping how packages are created, contributed, and selected across the software supply chain