AesFlushingCipher.smali

.class public final Lcom/google/android/exoplayer2/upstream/crypto/AesFlushingCipher;
.super Ljava/lang/Object;
.source "AesFlushingCipher.java"


# instance fields
.field private final blockSize:I

.field private final cipher:Ljavax/crypto/Cipher;

.field private final flushedBlock:[B

.field private pendingXorBytes:I

.field private final zerosBlock:[B


# direct methods
.method static constructor <clinit>()V
    .registers 1

    return-void
.end method

.method public constructor <init>(I[BJJ)V
    .registers 15
    .param p1, "mode"    # I
    .param p2, "secretKey"    # [B
    .param p3, "nonce"    # J
    .param p5, "offset"    # J

    .line 45
    invoke-direct {p0}, Ljava/lang/Object;-><init>()V

    .line 47
    :try_start_3
    const-string v0, "AES/CTR/NoPadding"

    invoke-static {v0}, Ljavax/crypto/Cipher;->getInstance(Ljava/lang/String;)Ljavax/crypto/Cipher;

    move-result-object v0

    iput-object v0, p0, Lcom/google/android/exoplayer2/upstream/crypto/AesFlushingCipher;->cipher:Ljavax/crypto/Cipher;

    .line 48
    invoke-virtual {v0}, Ljavax/crypto/Cipher;->getBlockSize()I

    move-result v0

    iput v0, p0, Lcom/google/android/exoplayer2/upstream/crypto/AesFlushingCipher;->blockSize:I

    .line 49
    new-array v1, v0, [B

    iput-object v1, p0, Lcom/google/android/exoplayer2/upstream/crypto/AesFlushingCipher;->zerosBlock:[B

    .line 50
    new-array v1, v0, [B

    iput-object v1, p0, Lcom/google/android/exoplayer2/upstream/crypto/AesFlushingCipher;->flushedBlock:[B

    .line 51
    int-to-long v1, v0

    div-long v1, p5, v1

    .line 52
    .local v1, "counter":J
    int-to-long v3, v0

    rem-long v3, p5, v3

    long-to-int v0, v3

    .line 53
    .local v0, "startPadding":I
    iget-object v3, p0, Lcom/google/android/exoplayer2/upstream/crypto/AesFlushingCipher;->cipher:Ljavax/crypto/Cipher;

    new-instance v4, Ljavax/crypto/spec/SecretKeySpec;

    iget-object v5, p0, Lcom/google/android/exoplayer2/upstream/crypto/AesFlushingCipher;->cipher:Ljavax/crypto/Cipher;

    .line 55
    invoke-virtual {v5}, Ljavax/crypto/Cipher;->getAlgorithm()Ljava/lang/String;

    move-result-object v5

    const-string v6, "/"

    invoke-static {v5, v6}, Lcom/google/android/exoplayer2/util/Util;->splitAtFirst(Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;

    move-result-object v5

    const/4 v6, 0x0

    aget-object v5, v5, v6

    invoke-direct {v4, p2, v5}, Ljavax/crypto/spec/SecretKeySpec;-><init>([BLjava/lang/String;)V

    new-instance v5, Ljavax/crypto/spec/IvParameterSpec;

    .line 56
    invoke-direct {p0, p3, p4, v1, v2}, Lcom/google/android/exoplayer2/upstream/crypto/AesFlushingCipher;->getInitializationVector(JJ)[B

    move-result-object v7

    invoke-direct {v5, v7}, Ljavax/crypto/spec/IvParameterSpec;-><init>([B)V

    .line 53
    invoke-virtual {v3, p1, v4, v5}, Ljavax/crypto/Cipher;->init(ILjava/security/Key;Ljava/security/spec/AlgorithmParameterSpec;)V

    .line 57
    if-eqz v0, :cond_49

    .line 58
    new-array v3, v0, [B

    invoke-virtual {p0, v3, v6, v0}, Lcom/google/android/exoplayer2/upstream/crypto/AesFlushingCipher;->updateInPlace([BII)V
    :try_end_49
    .catch Ljava/security/NoSuchAlgorithmException; {:try_start_3 .. :try_end_49} :catch_51
    .catch Ljavax/crypto/NoSuchPaddingException; {:try_start_3 .. :try_end_49} :catch_4f
    .catch Ljava/security/InvalidKeyException; {:try_start_3 .. :try_end_49} :catch_4d
    .catch Ljava/security/InvalidAlgorithmParameterException; {:try_start_3 .. :try_end_49} :catch_4b

    .line 64
    .end local v0    # "startPadding":I
    .end local v1    # "counter":J
    :cond_49
    nop

    .line 65
    return-void

    .line 60
    :catch_4b
    move-exception v0

    goto :goto_52

    :catch_4d
    move-exception v0

    goto :goto_52

    :catch_4f
    move-exception v0

    goto :goto_52

    :catch_51
    move-exception v0

    .line 63
    .local v0, "e":Ljava/security/GeneralSecurityException;
    :goto_52
    new-instance v1, Ljava/lang/RuntimeException;

    invoke-direct {v1, v0}, Ljava/lang/RuntimeException;-><init>(Ljava/lang/Throwable;)V

    throw v1
.end method

.method private getInitializationVector(JJ)[B
    .registers 6
    .param p1, "nonce"    # J
    .param p3, "counter"    # J

    .line 120
    const/16 v0, 0x10

    invoke-static {v0}, Ljava/nio/ByteBuffer;->allocate(I)Ljava/nio/ByteBuffer;

    move-result-object v0

    invoke-virtual {v0, p1, p2}, Ljava/nio/ByteBuffer;->putLong(J)Ljava/nio/ByteBuffer;

    move-result-object v0

    invoke-virtual {v0, p3, p4}, Ljava/nio/ByteBuffer;->putLong(J)Ljava/nio/ByteBuffer;

    move-result-object v0

    invoke-virtual {v0}, Ljava/nio/ByteBuffer;->array()[B

    move-result-object v0

    return-object v0
.end method

.method private nonFlushingUpdate([BII[BI)I
    .registers 12
    .param p1, "in"    # [B
    .param p2, "inOffset"    # I
    .param p3, "length"    # I
    .param p4, "out"    # [B
    .param p5, "outOffset"    # I

    .line 112
    :try_start_0
    iget-object v0, p0, Lcom/google/android/exoplayer2/upstream/crypto/AesFlushingCipher;->cipher:Ljavax/crypto/Cipher;

    move-object v1, p1

    move v2, p2

    move v3, p3

    move-object v4, p4

    move v5, p5

    invoke-virtual/range {v0 .. v5}, Ljavax/crypto/Cipher;->update([BII[BI)I

    move-result v0
    :try_end_b
    .catch Ljavax/crypto/ShortBufferException; {:try_start_0 .. :try_end_b} :catch_c

    return v0

    .line 113
    :catch_c
    move-exception v0

    .line 115
    .local v0, "e":Ljavax/crypto/ShortBufferException;
    new-instance v1, Ljava/lang/RuntimeException;

    invoke-direct {v1, v0}, Ljava/lang/RuntimeException;-><init>(Ljava/lang/Throwable;)V

    throw v1
.end method


# virtual methods
.method public update([BII[BI)V
    .registers 20
    .param p1, "in"    # [B
    .param p2, "inOffset"    # I
    .param p3, "length"    # I
    .param p4, "out"    # [B
    .param p5, "outOffset"    # I

    move-object v6, p0

    move/from16 v7, p2

    move/from16 v8, p3

    move/from16 v9, p5

    .line 75
    .end local p2    # "inOffset":I
    .end local p3    # "length":I
    .end local p5    # "outOffset":I
    .local v7, "inOffset":I
    .local v8, "length":I
    .local v9, "outOffset":I
    :cond_7
    iget v0, v6, Lcom/google/android/exoplayer2/upstream/crypto/AesFlushingCipher;->pendingXorBytes:I

    if-lez v0, :cond_25

    .line 76
    aget-byte v1, p1, v7

    iget-object v2, v6, Lcom/google/android/exoplayer2/upstream/crypto/AesFlushingCipher;->flushedBlock:[B

    iget v3, v6, Lcom/google/android/exoplayer2/upstream/crypto/AesFlushingCipher;->blockSize:I

    sub-int/2addr v3, v0

    aget-byte v2, v2, v3

    xor-int/2addr v1, v2

    int-to-byte v1, v1

    aput-byte v1, p4, v9

    .line 77
    add-int/lit8 v9, v9, 0x1

    .line 78
    add-int/lit8 v7, v7, 0x1

    .line 79
    add-int/lit8 v0, v0, -0x1

    iput v0, v6, Lcom/google/android/exoplayer2/upstream/crypto/AesFlushingCipher;->pendingXorBytes:I

    .line 80
    add-int/lit8 v8, v8, -0x1

    .line 81
    if-nez v8, :cond_7

    .line 82
    return-void

    .line 87
    :cond_25
    move-object v0, p0

    move-object v1, p1

    move v2, v7

    move v3, v8

    move-object/from16 v4, p4

    move v5, v9

    invoke-direct/range {v0 .. v5}, Lcom/google/android/exoplayer2/upstream/crypto/AesFlushingCipher;->nonFlushingUpdate([BII[BI)I

    move-result v10

    .line 88
    .local v10, "written":I
    if-ne v8, v10, :cond_33

    .line 89
    return-void

    .line 97
    :cond_33
    sub-int v11, v8, v10

    .line 98
    .local v11, "bytesToFlush":I
    iget v0, v6, Lcom/google/android/exoplayer2/upstream/crypto/AesFlushingCipher;->blockSize:I

    const/4 v12, 0x0

    const/4 v13, 0x1

    if-ge v11, v0, :cond_3d

    const/4 v0, 0x1

    goto :goto_3e

    :cond_3d
    const/4 v0, 0x0

    :goto_3e
    invoke-static {v0}, Lcom/google/android/exoplayer2/util/Assertions;->checkState(Z)V

    .line 99
    add-int/2addr v9, v10

    .line 100
    iget v0, v6, Lcom/google/android/exoplayer2/upstream/crypto/AesFlushingCipher;->blockSize:I

    sub-int v3, v0, v11

    iput v3, v6, Lcom/google/android/exoplayer2/upstream/crypto/AesFlushingCipher;->pendingXorBytes:I

    .line 101
    iget-object v1, v6, Lcom/google/android/exoplayer2/upstream/crypto/AesFlushingCipher;->zerosBlock:[B

    const/4 v2, 0x0

    iget-object v4, v6, Lcom/google/android/exoplayer2/upstream/crypto/AesFlushingCipher;->flushedBlock:[B

    const/4 v5, 0x0

    move-object v0, p0

    invoke-direct/range {v0 .. v5}, Lcom/google/android/exoplayer2/upstream/crypto/AesFlushingCipher;->nonFlushingUpdate([BII[BI)I

    move-result v0

    .line 102
    .end local v10    # "written":I
    .local v0, "written":I
    iget v1, v6, Lcom/google/android/exoplayer2/upstream/crypto/AesFlushingCipher;->blockSize:I

    if-ne v0, v1, :cond_58

    const/4 v12, 0x1

    :cond_58
    invoke-static {v12}, Lcom/google/android/exoplayer2/util/Assertions;->checkState(Z)V

    .line 105
    const/4 v1, 0x0

    .local v1, "i":I
    :goto_5c
    if-ge v1, v11, :cond_6a

    .line 106
    add-int/lit8 v2, v9, 0x1

    .end local v9    # "outOffset":I
    .local v2, "outOffset":I
    iget-object v3, v6, Lcom/google/android/exoplayer2/upstream/crypto/AesFlushingCipher;->flushedBlock:[B

    aget-byte v3, v3, v1

    aput-byte v3, p4, v9

    .line 105
    add-int/lit8 v1, v1, 0x1

    move v9, v2

    goto :goto_5c

    .line 108
    .end local v1    # "i":I
    .end local v2    # "outOffset":I
    .restart local v9    # "outOffset":I
    :cond_6a
    return-void
.end method

.method public updateInPlace([BII)V
    .registers 10
    .param p1, "data"    # [B
    .param p2, "offset"    # I
    .param p3, "length"    # I

    .line 68
    move-object v0, p0

    move-object v1, p1

    move v2, p2

    move v3, p3

    move-object v4, p1

    move v5, p2

    invoke-virtual/range {v0 .. v5}, Lcom/google/android/exoplayer2/upstream/crypto/AesFlushingCipher;->update([BII[BI)V

    .line 69
    return-void
.end method