...

Source file src/pkg/crypto/aes/cipher_s390x.go

     1	// Copyright 2016 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 aes
     6	
     7	import (
     8		"crypto/cipher"
     9		"crypto/internal/subtle"
    10		"internal/cpu"
    11	)
    12	
    13	type code int
    14	
    15	// Function codes for the cipher message family of instructions.
    16	const (
    17		aes128 code = 18
    18		aes192      = 19
    19		aes256      = 20
    20	)
    21	
    22	type aesCipherAsm struct {
    23		function code     // code for cipher message instruction
    24		key      []byte   // key (128, 192 or 256 bits)
    25		storage  [32]byte // array backing key slice
    26	}
    27	
    28	// cryptBlocks invokes the cipher message (KM) instruction with
    29	// the given function code. This is equivalent to AES in ECB
    30	// mode. The length must be a multiple of BlockSize (16).
    31	//go:noescape
    32	func cryptBlocks(c code, key, dst, src *byte, length int)
    33	
    34	func newCipher(key []byte) (cipher.Block, error) {
    35		// The aesCipherAsm type implements the cbcEncAble, cbcDecAble,
    36		// ctrAble and gcmAble interfaces. We therefore need to check
    37		// for all the features required to implement these modes.
    38		// Keep in sync with crypto/tls/common.go.
    39		if !(cpu.S390X.HasAES && cpu.S390X.HasAESCBC && cpu.S390X.HasAESCTR && (cpu.S390X.HasGHASH || cpu.S390X.HasAESGCM)) {
    40			return newCipherGeneric(key)
    41		}
    42	
    43		var function code
    44		switch len(key) {
    45		case 128 / 8:
    46			function = aes128
    47		case 192 / 8:
    48			function = aes192
    49		case 256 / 8:
    50			function = aes256
    51		default:
    52			return nil, KeySizeError(len(key))
    53		}
    54	
    55		var c aesCipherAsm
    56		c.function = function
    57		c.key = c.storage[:len(key)]
    58		copy(c.key, key)
    59		return &c, nil
    60	}
    61	
    62	func (c *aesCipherAsm) BlockSize() int { return BlockSize }
    63	
    64	func (c *aesCipherAsm) Encrypt(dst, src []byte) {
    65		if len(src) < BlockSize {
    66			panic("crypto/aes: input not full block")
    67		}
    68		if len(dst) < BlockSize {
    69			panic("crypto/aes: output not full block")
    70		}
    71		if subtle.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
    72			panic("crypto/aes: invalid buffer overlap")
    73		}
    74		cryptBlocks(c.function, &c.key[0], &dst[0], &src[0], BlockSize)
    75	}
    76	
    77	func (c *aesCipherAsm) Decrypt(dst, src []byte) {
    78		if len(src) < BlockSize {
    79			panic("crypto/aes: input not full block")
    80		}
    81		if len(dst) < BlockSize {
    82			panic("crypto/aes: output not full block")
    83		}
    84		if subtle.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
    85			panic("crypto/aes: invalid buffer overlap")
    86		}
    87		// The decrypt function code is equal to the function code + 128.
    88		cryptBlocks(c.function+128, &c.key[0], &dst[0], &src[0], BlockSize)
    89	}
    90	
    91	// expandKey is used by BenchmarkExpand. cipher message (KM) does not need key
    92	// expansion so there is no assembly equivalent.
    93	func expandKey(key []byte, enc, dec []uint32) {
    94		expandKeyGo(key, enc, dec)
    95	}
    96	

View as plain text